异步服务独立于Microsoft Dataverse核心操作,执行长时间运行的操作。 这样执行长时间运行的操作可以提高系统的整体性能和可伸缩性。 异步服务是一个托管的第一出(FIFO)队列,用于执行异步注册插件、工作流和操作,例如批量邮件、批量导入和市场活动传播。 这些操作注册到异步服务中,并在服务处理其队列时定期执行。
事件发生并处理任何同步扩展后,Dataverse 将序列化任何异步扩展的上下文,并将其保存在 系统作业(AsyncOperation)表中。 系统作业定义并跟踪异步操作的执行。 随着资源可用,Dataverse 处理系统作业并执行它们定义的操作。 Dataverse 在事件执行管道中再次处理扩展中定义的任何数据操作,但这次是同步操作。
执行顺序和依赖项
系统作业使用CreatedOn日期按照队列进行评估。 如果没有延迟执行的条件,则会在资源可用后立即执行它们。 执行并不总是按日期设置 CreatedOn 的顺序执行,因为不同类型的操作需要不同的资源。
系统作业可以依赖于另一个系统作业,以便它仅在其他系统作业完成之后才开始。
DependencyToken 列值在创建系统作业时将建立此依赖项。
DependencyToken如果值为 null,则系统作业没有依赖项。 从属系统作业具有相同 DependencyToken 的值,并按创建顺序执行。 如果系统作业被推迟,则所有后续依赖系统作业将继续等待,直到推迟的系统作业执行。
注释
注册以异步方式运行的插件无法使用此依赖项系统,因为系统会为其创建系统作业。
系统作业的安全注意事项
AsyncOperation (系统作业)表具有如下所述的分层权限模型。
实体级特权:具有写入权限(prvWrite)
AsyncOperation的用户可以更新支持的生命周期列(StateCode、、StatusCodePostPoneUntil)以管理系统作业。 这是用于取消、暂停、恢复或推迟作业的目标机制。内部列的平台级保护:包含内部执行数据的列(例如序列化作业有效负载)受独立于实体级特权强制实施的其他服务器端授权检查的保护。 这些保护可防止对作业执行数据进行未经授权的修改,即使是对表具有写入访问权限
AsyncOperation的用户也是如此。读取访问权限:具有读取权限(prvRead)
AsyncOperation的用户可以检索系统作业记录,包括作业名称、状态和时间戳等元数据。 这是特意设计的,以便用户可以监控作业进度和状态。
此分层模型可确保用户可以管理其系统作业的生命周期、预期操作和支持的操作,同时内部执行数据仍受平台保护。
管理系统任务
可以使用 AsyncOperation 表执行以下操作来管理系统作业。
- 检索系统任务
- 删除系统作业
- 管理系统作业状态
- 推迟系统作业
注释
不支持使用代码创建系统作业。 尽管 AsyncOperation 表支持多个可写列和创建操作,但仅以下列支持更新:
这些列允许用户具有适当的实体级写入特权(prvWrite) AsyncOperation 来管理系统作业的生命周期(取消、暂停、恢复和推迟)。
表中的其他列(包括内部执行数据)受其他平台级授权检查的约束,即使表架构指示这些列 AsyncOperation 是可写的,也无法通过标准更新操作进行修改。 架构级写入属性反映内部平台功能,而不是最终用户权限。
检索系统任务
可以通过导航到“设置系统>”在应用程序中查看>作业,还可以使用模型驱动应用中的高级查找来搜索它们。
使用代码可以检索系统作业,就像检索任何其他表一样。 下表列出了了解系统作业时非常重要的选定列:
| 列 | Description |
|---|---|
AsyncOperationId |
系统作业的唯一标识符。 |
CompletedOn |
完成系统作业的日期和时间。 |
CreatedBy |
创建系统作业的用户的唯一标识符。 |
CreatedOn |
创建系统作业的日期和时间。 |
Data |
与系统作业关联的非结构化数据。 |
DependencyToken |
具有相同依赖令牌的所有操作的执行将被序列化。 了解执行顺序和依赖项 |
Depth |
自第一次调用以来进行的 SDK 调用数。 |
ErrorCode |
从取消的系统作业返回的错误代码。 |
ExecutionTimeSpan |
系统作业执行所用的时间。 |
FriendlyMessage |
系统任务提供的消息。 |
IsWaitingForEvent |
指示系统任务正在等待事件。 |
Message |
与系统作业相关的消息。 |
MessageName |
启动此系统作业的消息的名称。 |
ModifiedBy |
上次修改系统作业的用户的唯一标识符。 |
ModifiedOn |
上次修改系统作业的日期和时间。 |
Name |
系统作业的名称。 |
OperationType |
系统作业的类型。 了解操作类型 |
OwnerId |
拥有系统作业的用户或团队的唯一标识符。 |
OwningBusinessUnit |
拥有系统作业的业务部门的唯一标识符。 |
OwningExtensionId |
与所属扩展关联的系统作业的唯一标识符。 |
OwningTeam |
拥有记录的团队的唯一标识符。 |
OwningUser |
拥有记录的用户的唯一标识符。 |
PostponeUntil |
指示系统作业是否仅在指定的日期和时间之后运行。 了解如何推迟系统作业 |
PrimaryEntityType |
系统作业主要关联的表的类型。 |
RecurrencePattern |
系统作业重复周期的模式。 了解重复开始时间和规律 |
RecurrenceStartTime |
定期模式的 UTC 开始时间。 了解重复开始时间和模式 |
RegardingObjectId |
与系统作业关联的对象的唯一标识符。 |
RetryCount |
重试系统作业的次数。 |
Sequence |
提交操作的顺序。 |
StartedOn |
启动系统作业的日期和时间。 |
StateCode |
系统作业的状态。 了解如何管理系统作业状态 |
StatusCode |
系统作业状态的原因。 了解如何管理系统作业状态 |
UTCConversionTimeZoneCode |
创建记录时正在使用的时区代码。 |
WorkflowStageName |
工作流阶段的名称。 |
示例
可以使用以下示例检索系统作业数据。
使用以下 Web API 查询检索上表中的列。 [了解如何使用 Web API 查询数据](webapi/query/overview.md
GET <organization URL>/api/data/v9.2/asyncoperations?$top=1000
&$select=
asyncoperationid,
completedon,
createdon,
data,
dependencytoken,
depth,
errorcode,
executiontimespan,
friendlymessage,
iswaitingforevent,
message,
messagename,
modifiedon,
name,
operationtype,
_ownerid_value,
postponeuntil,
primaryentitytype,
recurrencepattern,
recurrencestarttime,
_regardingobjectid_value,
retrycount,
sequence,
startedon,
statecode,
utcconversiontimezonecode,
workflowstagename
&$expand=
createdby($select=fullname),
modifiedby($select=fullname),
owningbusinessunit($select=name),
owningextensionid($select=name),
owningteam($select=name),
owninguser($select=fullname)
注释
使用 Web API,每个支持系统作业的表都有一个单值导航属性。 此导航属性的名称遵循模式 regardingobjectid_<table logical name>。
操作类型
OperationType 列描述系统作业的类别。 Dataverse 启动许多此类类型以执行维护任务。
注释
不能对平台生成的系统作业执行取消、暂停或恢复操作。
下表包含这些平台生成的作业的一些类型:
| OperationType 值 | OperationType 标签 |
|---|---|
| 9 | SQM 数据收集 |
| 16 | 收集组织统计信息 |
| 18 | 计算组织存储大小 |
| 19 | 收集组织数据库统计信息 |
| 20 | 集合组织大小统计信息 |
| 22 | 计算组织最大存储大小 |
| 24 | 更新统计信息间隔 |
| 25 | 组织全文文本目录索引 |
| 二十七 | 更新合同状态 |
| 31 | 存储限制通知 |
有关完整列表,请参阅 OperationType 选项
重复开始时间和模式
定期系统作业需要有关何时开始以及重复频率的信息。 这些值存储在 AsyncOperation 表 RecurrenceStartTime 和 RecurrencePattern 列中。
由于不能直接使用代码创建 AsyncOperation 记录,因此在查询数据时需要解释这些值。 这些属性值是通过使用用于创建新系统任务的消息来间接设置的。
BulkDelete 和 BulkDeleteDuplicates 消息都在相应的 Web API 操作或 .NET 请求类的 SDK 中包含参数或属性。 详细信息: BulkDetectDuplicatesRequest 类、BulkDetectDuplicates 操作、BulkDeleteRequest 类和BulkDelete 操作
RecurrenceStartTime 是一个日期时间值,用于指示系统作业何时应启动。 如果未进行设置,系统作业预计会立即启动。
该 RecurrencePattern 列存储有关定期系统作业发生的频率的信息。 创建新的异步记录时,平台有时会设置此值。 可以设置此值以更改模式。
此列的值使用 RFC2445 Internet 标准(Internet 日历和计划核心对象规范)的部分。
下表提供了示例:
| 循环模式 | 作业执行频率 |
|---|---|
FREQ=MONTHLY; |
每个月一次 |
FREQ=WEEKLY; |
每周一次 |
FREQ=DAILY; |
每天一次 |
FREQ=DAILY;INTERVAL=3; |
每三天 |
FREQ=HOURLY; |
每小时一次 |
如果未设置值 INTERVAL ,则会将其解释为 1。
诊断查询
使用本节中的查询来帮助诊断问题。
按州、状态和类型分类的作业
使用此查询可了解不同类型的作业的分布和频率。 结果可能会告诉你哪些作业导致了问题。
此查询不按 count 降序排序。 你可能希望改用 FetchXml 和 Web API。
使用 FetchXml 查询数据
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=groupby((statecode,statuscode,operationtype),aggregate($count as count))
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"
按计数列出的处于挂起状态的系统顶级作业
使用此查询提取AsyncOperation表中所有处于Suspended状态的作业的计数。 此查询可帮助你:
- 了解等待作业的数量和性质。
- 确定延误发生的位置。
- 就如何解决这些问题做出明智的决策,以提高系统性能和吞吐量。
此查询不按 count 降序排序。 你可能希望改用 FetchXml 和 Web API。
使用 FetchXml 查询数据
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=filter((statecode eq 1))/groupby((statecode,statuscode,operationtype),aggregate($count as count))
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"
结果中要查找的内容有:
量化挂起的作业:查询专门面向 挂起 的作业(
statecode=1)。 结果为你提供了按statuscode和operationtype分类的所有此类作业的计数。操作类型细目:已分组的
operationtype作业计数,显示操作类型最常处于挂起状态。识别潜在瓶颈:长时间挂起的作业计数较高可能是由于资源限制、对其他进程的依赖关系或系统配置不当导致的。
容量和资源管理:如果某些作业一致处于 “挂起 ”状态,则可能表示系统缺少有效处理这些作业所需的资源。
系统运行状况检查: 处于挂起 状态的作业充当运行状况指示器。 理想情况下,健康的系统应尽量减少处于“挂起”状态的作业,或者至少显示从“挂起”到活动处理的快速切换。
工作流效率:结果可以阐明工作流效率。 如果某个特定
operationtype作业的 挂起 作业计数较高,则可能意味着该工作流中的效率低下或需要优化。
按计数排序的工作流
此查询提供工作流相关作业的详细细分,按 operationtype 工作流的值进行筛选。 使用查询结果全面了解工作流作业、更有效地管理系统资源,并确保工作流运行顺利高效地运行。
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=filter((operationtype eq 10))/groupby((statecode,statuscode,operationtype),aggregate($count as count))
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"
结果中要查找的内容有:
特定工作流作业:筛选器将
operationtype=10结果限制为工作流作业。 可以看到有多少作业与工作流及其当前状态相关。 还可以将此示例查询应用于其他类型的操作。 详细了解操作类型作业状态分布:告知
statecode这些工作流作业的当前状态,例如它们是 就绪、 挂起、 锁定还是 已完成。Status Code Analysis:
statuscode可以深入了解作业当前状态背后的原因。 例如,它可以指示作业是否 正在等待资源、 正在等待、 正在进行、 暂停、 取消、 成功、 失败或 已取消。每个类别的计数:每个
statecode和statuscode组合的作业总数。 这有助于识别工作流操作的最常见结果。识别常见结果:通过按降序计数排序的结果,可以识别工作流处理中最常见的结果或瓶颈。
故障排除和优化: 失败 状态或 挂起 状态中的高计数可以突出显示工作流可能失败或停滞的区域,表明需要进行故障排除或进程优化。
性能指标:了解哪些工作流最为常见,以及它们在不同状态的分布方式有助于评估工作流管理系统的性能和可靠性。
容量规划: 持续大量的正在进行 或 等待 工作流可能表明需要更多资源来处理负载,或者需要优化工作流执行环境。
工作流管理:查询结果可以指导管理员更有效地管理工作流,例如确定哪些工作流优先顺序或确定可优化或停用/禁用的工作流。
系统运行状况检查:总体结果可以作为工作流系统的运行状况检查,指示系统是否以最佳方式执行,或者是否有需要注意的区域。
等待系统资源可用的作业
使用此查询从 AsyncOperation 表中检索作业的详细分析,这些作业处于特定就绪状态,但由于系统资源不可用,正在挂起等待执行。 此查询可以识别导致速度缓慢的因素,并做出决策以提高积压工作的效率以及更好地处理积压工作。
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=filter((statecode eq 0 and statuscode eq 0))/groupby((statecode,statuscode,operationtype),aggregate($count as count))
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"
结果中要查找的内容有:
筛选等待资源的就绪作业:限制结果为
statecode=0和statuscode=0中的作业,其中筛选器作用于处于“就绪”和“正在等待资源”状态的作业。 此组合表示作业已排队并准备运行,但目前处于暂停状态。优化作业计划:识别作业准备和等待时间中的模式可以通知作业计划改进,这可能会导致系统负载分布更加均衡。
识别基础问题:在某些情况下,等待资源的作业可能不仅仅是资源问题,但可能表明存在基础问题,例如死锁或低效的资源锁定机制。
文件存储查询
根据表的数据列AsyncOperation的大小,该列中的数据可能保存在文件存储中。 当行使用文件存储时,DataBlobId 列具有值。 若要节省空间,可能需要标识和删除这些记录。 使用以下查询发现这些记录
AsyncOperation 文件存储 数据块ID 计数
使用此查询计算表AsyncOperation中datablobid列不为 null 的记录数量。
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=filter((datablobid ne null))/aggregate($count as FileStorageCount)
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
这是您在结果中需要注意的内容:
数据存储影响:您可能想要删除记录以通过文件存储来节省空间,所以了解这一点很有帮助。 大数可能表明这些 Blob 使用的重要空间,这对于数据库大小管理来说可能很重要。
系统性能注意事项:如果
FileStorageCount意外高,可能需要采取进一步操作,例如批量删除和清理。
"AsyncOperations" 不在 Blob 存储中
使用此查询来计算AsyncOperation表中datablobid字段为NULL的记录数。
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=filter((datablobid eq null))/aggregate($count as DBCount)
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
在结果中要注意以下几点:
理解非 Blob 存储中的异步操作:
DBCount结果将指示没有关联数据 blob 的异步操作量。 这会显示不考虑 Blob 时的存储状态。识别低效环节 如果不是预期的结果,这里的高计数可能表明需要计划批量删除与清理。 在 blob 存储中计数低,而在此处计数高,则认为这是主要的数据量贡献者。
使用文件存储查找作业的名称
此查询的结果显示作业类型、作业的名称以及此作业在表上使用文件存储的次数。 使用此标识对文件消耗影响最大的特定作业名称,并为具有该名称的记录创建批量删除作业。
这将使能够识别出对文件消耗影响最大的特定作业名称。 因此,客户可以通过定位其名称来启动该特定作业的批量删除过程。
此查询不按 jobs 列递减排序。 你可能希望改用 FetchXml 和 Web API。
使用 FetchXml 查询数据
GET [Organization URI]/api/data/v9.2/asyncoperations?$apply=filter((datablobid ne null))/groupby((operationtype,name,friendlymessage),aggregate($count as jobs))
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"
AsyncOperation 文件大小和记录数量
使用此查询可以按状态、状态和所属扩展获取系统作业的总文件大小和记录计数。
此示例使用编码的 FetchXml 通过 Web API 发送查询。 使用 FetchXml 查询数据
GET [Organization URI]/api/data/v9.2/asyncoperations?fetchXml=%3Cfetch%20aggregate%3D%27true%27%3E%20%3Centity%20name%3D%27asyncoperation%27%3E%20%3Cattribute%20name%3D%27owningextensionid%27%20alias%3D%27owningextension%27%20groupby%3D%27true%27%20%2F%3E%20%3Cattribute%20name%3D%27statecode%27%20alias%3D%27statecode%27%20groupby%3D%27true%27%20%2F%3E%20%3Cattribute%20name%3D%27statuscode%27%20alias%3D%27statuscode%27%20groupby%3D%27true%27%20%2F%3E%20%3Cattribute%20name%3D%27operationtype%27%20alias%3D%27operationtype%27%20groupby%3D%27true%27%20%2F%3E%20%3Clink-entity%20name%3D%27fileattachment%27%20to%3D%27datablobid%27%20from%3D%27fileattachmentid%27%20alias%3D%27fileattachment%27%20link-type%3D%27inner%27%3E%20%3Cattribute%20name%3D%27filesizeinbytes%27%20alias%3D%27TotalSize%27%20aggregate%3D%27sum%27%20%2F%3E%20%3Cattribute%20name%3D%27filesizeinbytes%27%20alias%3D%27RecordCount%27%20aggregate%3D%27count%27%20%2F%3E%20%3Cfilter%3E%20%3Ccondition%20attribute%3D%27objectidtypecode%27%20operator%3D%27eq%27%20value%3D%274700%27%20%2F%3E%20%3C%2Ffilter%3E%20%3Corder%20alias%3D%27TotalSize%27%20descending%3D%27true%27%20%2F%3E%20%3C%2Flink-entity%3E%20%3C%2Fentity%3E%20%3C%2Ffetch%3E
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"
结果中要查找的内容有:
-
记录计数:
RecordCount指示要为每个系统作业记录分组返回多少条记录。 这将让你了解正在执行的异步操作量以及最常见的类型。 -
总文件大小:
TotalSize告知这些操作正在处理的数据量。 这有助于确定是否有任何可能影响系统性能的异常大型文件。 -
按拥有实体进行分组:查询按
owningextensionid、、owningextensionidnamestatecode、statuscode和operationtype对结果进行分组。 查看这些分组,以查明哪些扩展生成了最多的活动,以及是否存在主要特定操作类型。 -
操作状态和状态: 包含
statecode分组和statuscode分组将帮助你确定这些操作的当前状态和状态,例如哪些操作处于挂起状态、正在进行中或已完成。 -
按 TotalSize 排序: 由于结果按
TotalSize降序排序,因此请注意最上面的结果,因为它们将突出显示消耗最多存储的操作。 这对于确定优化或清理的潜在领域可能很重要。
删除系统作业
如果拥有必要的权限,可以在应用程序或代码中删除系统作业,就像任何其他表一样。
注释
注册异步插件时,可以选择自动删除成功的操作。 建议使用它。 了解如何编写插件
常见做法是创建定期批量删除作业,以删除成功的作业。 了解如何通过批量删除删除大量特定目标数据
管理系统作业状态
系统作业的状态会多次更改,直到操作完成。 以下是表示可用状态的 StateCode 选项和状态原因值的 StatusCode 选项:
| StateCode 值 | StateCode 标签 | 状态码的值 | StatusCode 标签 |
|---|---|---|---|
0 |
就绪 | 0 |
正在等待资源 |
1 |
暂停 | 10 |
等待中 |
2 |
Locked | 20 |
进行中 |
2 |
Locked | 21 |
暂停 |
2 |
Locked | 22 |
取消 |
3 |
Completed | 30 |
成功 |
3 |
Completed | 31 |
Failed |
3 |
Completed | 32 |
Canceled |
可以通过导航到“设置系统>”并使用“更多操作”>菜单中提供的命令来更改应用程序中系统作业的状态。
注释
您可以通过此 UI 执行的任何操作,也可以通过代码执行。 不能对平台生成的系统作业执行取消、暂停或恢复操作。 了解操作类型
除了用于管理视图的选项,可以使用以下用于管理系统作业的选项:
| Option | Description |
|---|---|
| Delete | 使用 。删除系统作业 |
| 批量删除 | 使用 “更多操作” 菜单。 打开向导以定义条件并创建新的批量删除系统作业以删除匹配的系统作业。 |
| 取消 | 使用 “更多操作” 菜单。 取消系统作业。 |
| 继续 | 使用 “更多操作” 菜单。 恢复暂停的系统作业。 |
| 推迟 | 使用 “更多操作” 菜单。 重新计划系统作业 |
| 暂停 | 使用 “更多操作” 菜单。 暂停系统作业。 |
请求的操作是否发生取决于系统作业的状态。 例如,无法暂停已完成或尚未启动的作业。 下表描述了每个更改的条件,以及选择这些更改时会发生什么情况。
| Option | 有效的 StateCode 值 | 更改 |
|---|---|---|
| 删除 | 任意 | 系统作业已删除 |
| 取消 |
0 (就绪) 1 (已暂停) 2 (已锁定) |
StateCode 更改为 3 (已完成) 并 StatusCode 更改为 32 (已取消), 或 StateCode 更改为 3 (已完成) 并 StatusCode 更改为 31 (失败) |
| Resume |
1 (已暂停) |
StateCode 已更改为 0 (就绪) |
| 延期 |
0 (就绪) 2 (已锁定) |
“推迟作业”对话框提示用户输入日期/时间值以推迟系统作业。 了解如何推迟系统作业 |
| 暂停 |
2 (已锁定) |
StateCode 已更改为 1 (已挂起) |
推迟系统作业
当系统作业将状态从 PostPoneUntil (1) 更改为 (0) 时,该列包含日期/时间值。
PostPoneUntil列,StateCode列和StatusCode列是唯一支持更新的AsyncOperation表列。
。