使用 ExecuteMultiple 提高批量数据加载的性能
发布日期: 2017年1月
适用于: Dynamics 365 (online),Dynamics 365 (on-premises),Dynamics CRM 2016,Dynamics CRM Online
您可以使用 ExecuteMultipleRequest 消息在 Microsoft Dynamics 365(在线或本地)中支持更高吞吐批量消息传递方案,尤其在 Internet 延迟可能是最大限制因素的 Microsoft Dynamics 365 (online) 中。ExecuteMultipleRequest 接受消息 Requests输入集合,按消息请求在输入集合中出现的顺序执行每个消息请求,还可以返回包含发生的每个消息的响应或错误的Responses 的集合。 输入集合中的每个消息请求都在单独的数据库事务中进行处理。 使用 IOrganizationService执行ExecuteMultipleRequest。Execute 方法。
通常,ExecuteMultipleRequest 的行为与您在输入请求集合中单独执行每个消息请求时相同,但性能更高。 提倡使用服务代理的 CallerId 参数,它适用于执行输入请求集合中的每个消息。 当您期望处理每个消息时,执行插件和工作流活动。
插件和自定义工作流活动形式的自定义代码甚至可以执行 ExecuteMultipleRequest。 不过,需要记住一些要点。 同步注册的插件引发的异常在响应集合项 Fault 参数中返回。 如果插件在数据库事务内部执行,插件执行 ExecuteMultipleRequest,且启动事务回滚,则回滚包括 ExecuteMultipleRequest 执行请求导致的所有数据更改。
本主题内容
示例
指定运行时执行选项
运行时限制
处理批量大小错误
示例
以下示例代码演示执行多个创建操作的单一 ExecuteMultipleRequest。 称作设置的运行时执行选项用于控制请求处理和返回的结果。 下一节将讨论这些运行时选项。
// Get a reference to the organization service.
using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,serverConfig.Credentials, serverConfig.DeviceCredentials))
{
// Enable early-bound type support to add/update entity records required for this sample.
_serviceProxy.EnableProxyTypes();
#region Execute Multiple with Results
// Create an ExecuteMultipleRequest object.
requestWithResults = new ExecuteMultipleRequest()
{
// Assign settings that define execution behavior: continue on error, return responses.
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
// Create an empty organization request collection.
Requests = new OrganizationRequestCollection()
};
// Create several (local, in memory) entities in a collection.
EntityCollection input = GetCollectionOfEntitiesToCreate();
// Add a CreateRequest for each entity to the request collection.
foreach (var entity in input.Entities)
{
CreateRequest createRequest = new CreateRequest { Target = entity };
requestWithResults.Requests.Add(createRequest);
}
// Execute all the requests in the request collection using a single web method call.
ExecuteMultipleResponse responseWithResults =
(ExecuteMultipleResponse)_serviceProxy.Execute(requestWithResults);
// Display the results returned in the responses.
foreach (var responseItem in responseWithResults.Responses)
{
// A valid response.
if (responseItem.Response != null)
DisplayResponse(requestWithResults.Requests[responseItem.RequestIndex], responseItem.Response);
// An error has occurred.
else if (responseItem.Fault != null)
DisplayFault(requestWithResults.Requests[responseItem.RequestIndex],
responseItem.RequestIndex, responseItem.Fault);
}
' Get a reference to the organization service.
_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig)
Using _serviceProxy
' Enable early-bound type support to add/update entity records required for this sample.
_serviceProxy.EnableProxyTypes()
'#Region "Execute Multiple with Results"
' Create an ExecuteMultipleRequest object.
' Assign settings that define execution behavior: continue on error, return responses.
' Create an empty organization request collection.
requestWithResults = New ExecuteMultipleRequest() With
{
.Settings = New ExecuteMultipleSettings() With
{
.ContinueOnError = False,
.ReturnResponses = True
},
.Requests = New OrganizationRequestCollection()
}
' Create several (local, in memory) entities in a collection.
Dim input As EntityCollection = GetCollectionOfEntitiesToCreate()
' Add a CreateRequest for each entity to the request collection.
For Each entity In input.Entities
Dim createRequest_Renamed As CreateRequest = New CreateRequest With {.Target = entity}
requestWithResults.Requests.Add(createRequest_Renamed)
Next entity
' Execute all the requests in the request collection using a single web method call.
Dim responseWithResults As ExecuteMultipleResponse =
CType(_serviceProxy.Execute(requestWithResults), ExecuteMultipleResponse)
' Display the results returned in the responses.
For Each responseItem In responseWithResults.Responses
If responseItem.Response IsNot Nothing Then
' A valid response.
DisplayResponse(requestWithResults.Requests(responseItem.RequestIndex),
responseItem.Response)
ElseIf responseItem.Fault IsNot Nothing Then
' An error has occurred.
DisplayFault(requestWithResults.Requests(responseItem.RequestIndex),
responseItem.RequestIndex, responseItem.Fault)
End If
Next responseItem
若要查看完整示例,请参阅示例:执行多个请求。
指定运行时执行选项
ExecuteMultipleRequest 的 Settings 参数适用于控制执行行为和返回结果的请求集合中的所有请求。 我们更详细地看一下这些选项。
ExecuteMultipleSettings 成员 |
说明 |
---|---|
当为 true 时,继续处理集合中的下一个请求,即使从集合中当前请求的处理中返回错误。 当为 false 时,不要继续处理下一个请求。 |
|
当为 true 时,从处理的每个消息请求返回响应。 当为 false 时,不返回响应。 如果设置为 true 且请求不返回一个响应,由于这是其设计,因此该请求的 ExecuteMultipleResponseItem 设置为 null。 不过,即使为 false,如果返回错误, Responses 程序集将不为空。 如果返回错误,则每个已处理请求的集合中将有一个响应项返回错误,Fault 将设置为发生的实际错误。 |
例如,在包含六个请求的请求集合中(第三个和第五个请求返回错误),下表说明了 Responses 集合将包含的内容。
设置 |
响应集合内容 |
---|---|
ContinueOnError=true,ReturnResponses=true |
6 个响应项:2 个将 Fault 设置为值。 |
ContinueOnError=false,ReturnResponses=true |
3 个响应项:1 个将 Fault 设置为值。 |
ContinueOnError=true,ReturnResponses=false |
2 个响应项:2 个将 Fault 设置为值。 |
ContinueOnError=false,ReturnResponses=false |
1 个响应项:1 个将 Fault 设置为值。 |
响应项中的 RequestIndex 参数表示响应关联的请求的序列号(从零开始)。 在上述示例中,第三个请求的请求索引为 2。
运行时限制
对于 ExecuteMultipleRequest 的使用,有一些限制,如下表所述。
不允许递归 - ExecuteMultipleRequest 不能调用 ExecuteMultipleRequest。 请求集合中的 ExecuteMultipleRequest 将生成该请求项的错误。
最大批量大小 – 对于可添加到请求集合的请求数量,存在一定限制。 如果超过该限制,则在执行第一个请求后引发错误。 尽管可以为 Microsoft Dynamics 365 部署设置最大数量为 1000 个请求,但是通常限制 1000 个请求。 此限制的部署设置为 BatchSize。
并行呼叫限制 – 对于 Microsoft Dynamics 365 (online),每个组织限制为有 2 个并发 ExecuteMultipleRequest 执行。 如果超过该限制,则在执行第一个请求后引发“服务器忙”错误。 对于内部部署,默认情况下不启用限制。 此限制的部署设置为 ExecuteAsyncPerOrgMaxConnectionsPerServer。
提示
对于所有 Dynamics 365 部署,部署管理员可以设置或更改限制。
处理批量大小错误
当输入请求集合超出最大批量大小时,应怎么办? 您的代码无法直接通过部署 Web 服务查询最大批量大小,除非它在具有部署管理员角色的帐户下运行。
幸运的是,您可以使用另一种方法。 在输入 Requests 集合中的请求数超出组织允许的最大批量大小时,会从 ExecuteMultipleRequest 调用返回错误。 最大批量大小在错误中返回。 您的代码可以检查该值,将输入请求集合调整到指示的限制范围内,然后重新提交 ExecuteMultipleRequest。 以下代码段演示该逻辑的一些部分。
catch (FaultException<OrganizationServiceFault> fault)
{
// Check if the maximum batch size has been exceeded. The maximum batch size is only included in the fault if it
// the input request collection count exceeds the maximum batch size.
if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
{
int maxBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
if (maxBatchSize < requestWithResults.Requests.Count)
{
// Here you could reduce the size of your request collection and re-submit the ExecuteMultiple request.
// For this sample, that only issues a few requests per batch, we will just print out some info. However,
// this code will never be executed because the default max batch size is 1000.
Console.WriteLine("The input request collection contains %0 requests, which exceeds the maximum allowed (%1)",
requestWithResults.Requests.Count, maxBatchSize);
}
}
// Re-throw so Main() can process the fault.
throw;
}
Catch fault As FaultException(Of OrganizationServiceFault)
' Check if the maximum batch size has been exceeded. The maximum batch size is only included in the fault if it
' the input request collection count exceeds the maximum batch size.
If fault.Detail.ErrorDetails.Contains("MaxBatchSize") Then
Dim maxBatchSize As Integer = Convert.ToInt32(fault.Detail.ErrorDetails("MaxBatchSize"))
If maxBatchSize < requestWithResults.Requests.Count Then
' Here you could reduce the size of your request collection and re-submit the ExecuteMultiple request.
' For this sample, that only issues a few requests per batch, we will just print out some info. However,
' this code will never be executed because the default max batch size is 1000.
Console.WriteLine("The input request collection contains %0 requests, which exceeds the maximum allowed (%1)", requestWithResults.Requests.Count, maxBatchSize)
End If
End If
' Re-throw so Main() can process the fault.
Throw
End Try
另请参阅
Execute
OrganizationRequest
OrganizationResponse
使用组织服务读取和写入数据或元数据
组织服务中的 xRM 消息
Discovery Service 中的消息
组织服务中的 Dynamics 365 消息
导入数据
Microsoft Dynamics 365
© 2017 Microsoft。 保留所有权利。 版权