Introduction:
ExecuteMultipleRequest – Message that allows you to club multiple CRM operations and execute them at one go without having to send each of these as separate requests. The ExecuteMultiple provides you with the option to indicate whether you want to continue processing the remaining requests if one of them fails or to stop processing. But the request that was successfully executed does not rollback if any of the later requests fails.
Plugin & Workflow Execution: Plugin and workflow assemblies are executed within a transaction now. Any error within the plugin would roll back the original operation as well as any related operations you may have performed.
What happens if you use Execute Multiple within Plugin or Workflow assembly?
In the example below, we are performing multiple CRUD operations on records and each of these operations have been clubbed into the organization request collection and passed to the ExecuteMultiple request.
IPluginExecutionContext context = localContext.PluginExecutionContext; Entity preImageEntity = (context.PreEntityImages != null && context.PreEntityImages.Contains(this.preImageAlias)) ? context.PreEntityImages[this.preImageAlias] : null; Entity postImageEntity = (context.PostEntityImages != null && context.PostEntityImages.Contains(this.postImageAlias)) ? context.PostEntityImages[this.postImageAlias] : null; // TODO: Implement your custom Plug-in business logic. IOrganizationService _service = localContext.OrganizationService; try { ExecuteMultipleRequest executeMultipe = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; Entity cnt = new Entity("contact"); cnt["firstname"] = "dev"; cnt["lastname"] = "smith"; CreateRequest createReq1 = new CreateRequest() { Target = cnt }; executeMultipe.Requests.Add(createReq1); Entity cnt1 = new Entity("contact"); cnt1["firstname"] = "viky"; cnt1["lastname"] = "border"; CreateRequest createReq2 = new CreateRequest() { Target = cnt1 }; executeMultipe.Requests.Add(createReq2); Entity cnt2 = new Entity("contact"); cnt2.Id = new Guid("2F7C6094-E86B-E511-80E0-3863BB3C0130"); cnt2["firstname"] = "allen"; UpdateRequest createReq3 = new UpdateRequest() { Target = cnt2 }; executeMultipe.Requests.Add(createReq3); EntityReference cnt3 = new EntityReference() { LogicalName = "contact", Id = new Guid("2F7C6094-E86B-E511-80E0-3863BB3C0130") }; DeleteRequest createRez = new DeleteRequest() { Target = cnt3 }; ExecuteMultipleResponse responseWithResults = (ExecuteMultipleResponse)_service.Execute(executeMultipe); throw new InvalidPluginExecutionException("Manual exception");
Result:
Since the CRUD operations were part of the ExecuteMultiple request, these are actually committed to the database, even though there was an explicit exception thrown from the Plugin.
Conclusion:
When ExecuteMultiple is included within a Plugin or Workflow assembly, it is being executed within its own space that is different from the Plugin or workflow transaction and any error within the code does not rollback the operations performed through the Execute Multiple request. This behavior is different from the standard expected behavior of Plugins and not sure if this is a bug or a design feature of Execute Multiple.
You may also like to see : InoLink – Dynamics CRM and QuickBooks Integration.