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.
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.
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
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.