Archive for April 10, 2018

Transaction aware batch processing using ‘ExecuteMultipleRequest’

April 10, 2018 4 comments

In this article, I am going to discuss about transaction aware batch processing in ExecuteMultipleRequest using  ExecuteTransactionRequest.

Is ‘ExecuteMultipleRequest’ not a transaction aware?

  • By design, ‘ExecuteMultipleRequest’ is non-transactional.
  • Which means ‘Request’ objects added to ‘ExecuteMultipleRequest’ are independent of each other and if any exception occurred in any of the ‘Request’ will not roll back previously committed ‘Requests’.
  • However you have an option to stop the batch (i.e., By setting ContinueOnError = false),  if any exception occurs.
  • Important to note is that, this behavior is not a transaction aware and ‘Requests’ executed prior to the error, will still be committed.

How can we achieve ‘Transaction’ in Batch execution?

  • Using ExecuteTransactionRequest, we can achieve ‘Transaction’ (i.e., Commit and Rollback) in Batch execution
  • ExecuteTransactionRequest will execute the all the ‘Requests’ in a single transaction.
  • If any exception occurred in any of the ‘Request’ execution, will roll back all the previously executed ‘Requests’.

Then why do we need ‘Transaction aware’ feature in ‘ExecuteMultipleRequest’?

  • ‘ExecuteMultipleRequest’ has an option to either stop the operation or suppress the exception, if any exception occurs, using ContinueOnError property.
  • However there is no option to achieve ‘Transactional Batch feature’ in ExecuteMultipleRequest.

Lets see how we get both features together in ‘ExecuteMultipleRequest’?

[Code snippet] ‘ExecuteMultipleRequest’ with ‘Transaction aware’ option

  • ‘ExecuteMultipleRequest’ can have ‘ExecuteTransactionRequest’ object as a ‘Request’, and as we know ‘ExecuteTransactionRequest’ is transaction aware, it get executed in transaction.

var connectionString = ConfigurationManager.ConnectionStrings[“Xrm”].ConnectionString;
CrmServiceClient crmConn = new CrmServiceClient(connectionString);

// Instantiate ExecuteMultiple
var reqExecMultiple = new ExecuteMultipleRequest(){
Requests = new OrganizationRequestCollection(),
Settings = new ExecuteMultipleSettings(){
ContinueOnError = false,
ReturnResponses = true

// Instantiate ExecuteTransaction
var reqExecTransaction = new ExecuteTransactionRequest(){
Requests = new OrganizationRequestCollection()

// Add 20 requests of type ‘CreateRequest’ to ‘Execute Transaction’
for (int indxStudent = 0; indxStudent < 20; indxStudent++){
// Instantiate ‘Student’ record
var entStudent = new Entity(“new_student”);
entStudent[“new_name”] = “Student : ” + indxStudent.ToString();

// Instantiate ‘CreateRequest’
CreateRequest reqCreate = new CreateRequest{
Target = entStudent

// Add ‘CreateRequest’ object to ‘ExecuteTransaction’ Requests collection

// Execute the ‘Execute Multiple Request’
using (_serviceProxy = crmConn.OrganizationServiceProxy){
_service = _serviceProxy;

// Add ‘Execute Transaction’ request object to ‘ExecuteMulitple’ Requests collection

// Execute Multiple Request
var response = (ExecuteMultipleResponse)_service.Execute(reqExecMultiple);

// Read the GUID of created Students
foreach (var responseItem in response.Responses){
var execTransactionResponse = (ExecuteTransactionResponse)responseItem.Response;
foreach (var createResponse in execTransactionResponse.Responses){
Console.WriteLine(“Student created: {0}”, ((CreateResponse)createResponse).id);


Key Notes:

  • ‘ExecuteTransactionRequest’ cannot contain either ‘ExecuteTransactionRequest’ or ‘ExecuteMultipleRequest’ messages.
  • Its recommended to not use ‘ExecuteTransactionRequest’ or ‘ExecuteMultipleRequest’ in Plug-ins. Refer article.
  • Operations included in a batch request are executed sequentially and aren’t done in parallel.
  • ‘ExecuteTransactionRequest’ may potentially block the database for the duration of the long-running transaction, so use it judiciously.