D365 Integration – Handling concurrent transactions
In one of our integration requirements, we got to make sure that there wont be any concurrent updates/deletion to the records, to avoid data loss.
As an example, lets assume a Record 1 was retrieved by users U1 and U2 and both want to update ‘Name’ field same time, in this scenario it could end up with either U1 or U2 overriding each others data.
In such scenarios we can prevent the data loss using Optimistic Concurrency.
Whats an ‘Optimistic Concurrency’?
- This feature provides the ability for your applications to detect whether an entity record has changed on the server in the time between when your application retrieved the record and when it tries to update or delete that record.
- If you notice, every entity will have an OOB field ‘VersionNumber’ of type ‘Time Stamp’.
- ‘VersionNumber’ value gets updated by system, every time when the record updates.
- In below screen, my record ‘Transaction’ has the ‘Name’ set to ‘Payment to UBER‘.
- Let me retrieve the record and before triggering update, let me update the ‘Name’ field to ‘Payment to UBER_Updated‘.
- Now the Update fails with error code.
- The update would go through, if there wont be any updates post retrieve.
C# Code snippet:
var queryTransaction = new QueryExpression(“raj_transaction”){
ColumnSet = new ColumnSet(“versionnumber”, “raj_name”)
};var transactions = _service.RetrieveMultiple(queryTransaction);
foreach (var transaction in transactions.Entities){
// transaction.RowVersion// Update Name
transaction[“raj_name”] = DateTime.Now.ToString();//Update the account
var request = new UpdateRequest()
{
Target = transaction,
ConcurrencyBehavior = ConcurrencyBehavior.IfRowVersionMatches
};try{
_service.Execute(request);
}
catch (FaultException<OrganizationServiceFault> ex){
switch (ex.Detail.ErrorCode){
case -2147088254: // ConcurrencyVersionMismatch
case -2147088253: // OptimisticConcurrencyNotEnabled
throw new InvalidOperationException(ex.Detail.Message);
case -2147088243: // ConcurrencyVersionNotProvided
throw new ArgumentNullException(ex.Detail.Message);
default:
throw ex;
}
}
}
Notes:
- Optimistic concurrency is supported on all out-of-box entities enabled for offline sync and all custom entities.
- You can determine if an entity supports optimistic concurrency by retrieving the entity’s metadata using code or by viewing the metadata using the Metadata Browser IsOptimisticConcurrencyEnabled is set to true.
- Refer my older article on Optimistic concurrency using WEB API in client script.
- Refer article for more details.
🙂