Impressive Magazine

Managing Concurrency in Dynamics CRM by Taking Auto Number Generation As An Example

In this blog, CRM development services providers are explaining the way to manage concurrency in Dynamics CRM by taking Autonumber generation reference. You can read this post and find what they are following to make this happen.

Dynamics CRM/365 is multi-user application that supports threading. When there is high volume of read/update/delete actions, there might be new set of problems associated with data loss.

Think about these scenarios.

  1. A record is updated by CRM user when it is being edited by another user.
  2. A record is deleted by CRM user when it is being edited by another user.

There is decent probability of such scenarios when there are many concurrent users working on the records in parallel. Dynamics CRM 2015 Update 1 introduces a feature called Optimistic Concurrency to handle such scenarios during coding. This feature allows developers to keep track of versions of updates happened on a particular record and to detect possible concurrent updates.

Case study: Auto Number for Case Entity

Enabling Optimistic Concurrency

Handling Concurrency

Understanding Concurrency Behavior

The messages such as UpdateRequest and DeleteRequest have ConcurrencyBehavior property which can be set by the user. According to https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.concurrencybehavior.aspx, Concurrency Behavior is enum property that has following values

// Code starts here

// Plugin for Case entity on create message and on pre stage event

if (context.InputParameters.Contains("Target") &&

               context.InputParameters["Target"] is Entity)

            {

                Entity incident = (Entity)context.InputParameters["Target"];

                // Pull config records from CRM

                // Key name is CaseAutoNumber

                string query = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>

  <entity name='crm_config'>

    <attribute name='crm_key' />

    <attribute name='crm_value' />

    <filter type='and'>

      <condition attribute='statecode' operator='eq' value='0' />

      <condition attribute='crm_key' operator='eq' value='CaseAutoNumber' />

    </filter>

  </entity>

</fetch>";

                EntityCollection collection = service.RetrieveMultiple(new FetchExpression(query));

                if (collection.Entities.Count > 0)

                {

                    Entity config = collection.Entities.FirstOrDefault();

                    int value = Convert.ToInt32(config.Attributes["crm_value"].ToString());

                    //update case record

                    incident.Attributes.Add("crm_casenumber", value.ToString());

                    try

                    {

                        // update config

                        config.Attributes["crm_value"] = (value + 1).ToString();

                        UpdateRequest updateRequest = new UpdateRequest();
 


                        // We are updating only if row version matches. Otherwise, we need to handle exception

                        updateRequest.ConcurrencyBehavior = ConcurrencyBehavior.IfRowVersionMatches;

                        updateRequest.Target = config;

                        updateRequest.Target.RowVersion = rowVersion;

                        service.Execute(updateRequest);

                    }

                    catch (FaultException<OrganizationServiceFault> ex)

                    {

                        //Faultcode for ConcurrencyVersionMismatch, it means that record has been changed by someone after record is retrieved and before the update action happens.

                        if (ex.Code.Name == "ConcurrencyVersionMismatch")

                        {

                            throw new InvalidPluginExecutionException("Create record again");

                        }

                    }

          }

}

//Code ends here

Conclusion:

Hence, it is always a good practice to use optimistic concurrency to prevent data loss especially when data is very important. Also, enabling auditing would help to keep track of changes happened for that record.

This is a case study shared by CRM development services providers to help community people. They have discussed the best way to manage concurrency in Dynamics CRM by taking Autonumber generation reference. If you have any question, ask in comments at the end of this post.