执行多个请求的主要目的是通过减少通过网络传输的数据总量来提高高延迟环境中的性能。
可以使用ExecuteMultipleRequest消息来支持Microsoft Dataverse中更高的吞吐量批量消息传递方案。 ExecuteMultipleRequest 接受消息的输入集合 Requests,按照它们在输入集合中出现的顺序执行消息请求,并可选择返回一个集合 Responses,其中包含每条消息的响应或发生的错误。 input 集合中的每个消息请求都在单独的数据库事务中处理。 使用 IOrganizationService.Execute 方法执行 ExecuteMultipleRequest。
通常, ExecuteMultipleRequest 其行为与单独执行 input 请求集合中的每个消息请求相同,只是性能更好。 服务代理支持使用 CallerId 参数,并将该参数应用于输入请求集合中每条消息的执行过程。 插件和工作流活动对于处理的每条消息均按预期运行。
插件和自定义工作流活动可以使用 ExecuteMultipleRequest。 但是,不建议使用此方法。 同步步骤中的任何失败都必须回滚所有数据操作,以维护数据完整性。 在 ExecuteMultiple 中执行的每个操作都必须回滚。
ExecuteMultiple 当操作时间超过插件超时的最大时长时,也会引发问题。
详细信息: 不要在插件和工作流活动中使用批处理请求类型
Example
下面的示例代码演示了一个执行多个创建操作的单个 ExecuteMultipleRequest 代码。 名为 “设置” 的运行时执行选项控制请求处理和返回的结果。 下一部分讨论这些运行时选项。
// Create an ExecuteMultipleRequest object.
ExecuteMultipleRequest 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)service.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);
}
详细信息: 示例:执行多个请求
指定运行时执行选项
ExecuteMultipleRequest应用于Settings请求集合中的所有请求的参数,并控制执行行为和返回的结果。
| ExecuteMultipleSettings 成员 | Description |
|---|---|
| ContinueOnError | 当 true 时,即使处理集合中的当前请求时返回错误,也继续处理集合中的下一个请求。 当 false,不要继续处理下一个请求。 |
| ReturnResponses | 当 true 时,返回已处理的每个消息请求的响应。 当false时,不要返回响应。如果设置为 true,并且某个请求因其设计本就不会返回响应,则该请求的 ExecuteMultipleResponseItem 会被设置为 null。但是,即使在 false 的情况下,如果返回了错误,Responses 集合也不会为空。 返回错误时,对于每个返回故障的已处理请求,集合中都有一个响应项,并且 Fault 被设置为实际发生的故障。 |
例如,在一个包含六个请求的请求集合中,如果第三个和第五个请求返回错误,下表显示 Responses 集合将包含哪些内容。
| Settings | 响应集合的内容 |
|---|---|
| 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,它将为该请求项生成错误。
- 最大批大小 只能向请求集合添加有限数量的请求。 如果超出该限制,系统会在执行第一个请求之前引发错误。 限制为 1,000 个请求是典型的,但可以为 Dataverse 部署设置此最大数量。
Note
并发执行的 ExecuteMultiple 请求数量曾受到限制。 限制为 2。 Microsoft删除了此限制,因为服务保护限制使得它变得没有必要。 有关详细信息,请参阅 服务保护 API 限制。
处理批处理大小异常
如果输入请求集合超过最大批大小,该怎么办? 除非代码使用具有部署管理员角色的帐户运行,否则无法直接通过部署 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
// 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;
}
另见
将消息与用于 .NET 的 SDK 配合使用
使用 ExecuteAsync
使用 ExecuteTransaction