C# Code · Customization and Configuration · Data Migration And Integration

{Common Data Service} Apply Optimistic concurrency using Organization Service

Introduction

On a multi-threaded and multi-user system like Power Apps, operations and data changes often happen in parallel. A problem arises when two or more update or delete operations on the same piece of data happen at the same time. This situation could potentially result in data loss. The optimistic concurrency 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.

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, and check if the attribute IsOptimisticConcurrencyEnabled is set to true. For custom entities, this property is set to true by default.

Problem Statement

We wanted to integrate Account data from external system through Organization Service. We needed to check if data is modified in CRM Dynamics once we sync the data from external system, if yes we did not wanted to update that record instead fetch the latest data from Dynamics and then perform update.

try
                {
                    //Retrieve Account Record "A. Datu Corporation (sample)"
                    Entity accountRecord = cdsClient.Retrieve("account", new Guid("1462dec1-eef0-ea11-a817-000d3a8ccd71"), new ColumnSet(true));
                    //Code to Update the Record
                    //Initialize new Object to update
                    Entity updateRecord = new Entity();
                    updateRecord.Id = accountRecord.Id;
                    updateRecord.LogicalName = accountRecord.LogicalName;
                    //Set the RowVersion Property of the Updating record
                    updateRecord.RowVersion = accountRecord.RowVersion;
                    //Update Name
                    updateRecord["name"] = "Account Changed";
                    UpdateRequest updateReq = new UpdateRequest();
                    updateReq.Target = updateRecord;
                    //Set the Concurrency Behaviour before executing the Update request & match the Row Versions of the record before executing the Request
                    updateReq.ConcurrencyBehavior = ConcurrencyBehavior.IfRowVersionMatches;
                    // Do the update.
                    UpdateResponse updateResponse = (UpdateResponse)cdsClient.Execute(updateReq);

                }
                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;
                    }
                }

To determine whether the entity has been changed, you don’t need to compare all the values, you can use the RowVersion property to see if it has changed.

If the RowVersion doesn’t match, an error with the message The version of the existing record doesn't match the RowVersion property provided. will occur.

If you always want to overwrite the changes then set ConcurrencyBehaviour to AlwaysOverwrite

enum ConcurrencyBehavior
{
Default = 0,
IfRowVersionMatches = 1,
AlwaysOverwrite = 2
}

If you want to implement Cncurrency Behaviour in plugin code. Please check below link.

https://medium.com/capgemini-microsoft-team/optimistic-concurrency-in-dynamics-365-forms-7b4fecc08511

Note

  1. When you create Custom entity optimistic concurrency is enabled by default
  2. You can also use ConcurrencyBehavior for DeleteRequest
  3. RowVersion property returns null in plugin Input Parameter Target
  4. Optimistic concurrency behavior can only be set through an SDK call. There is presently no setting for it in a form of the Web application.

Hope this helps!

One thought on “{Common Data Service} Apply Optimistic concurrency using Organization Service

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s