I have some modification this great solution (concurrent access)

Mar 28 at 12:54 PM
Edited Mar 31 at 6:16 AM
my modifications prevent concurrent access, i added lock for record to waiting, then other process is finished.
a) create string field au_entityid in entity au_counterconfiguration
b) this code was added to the existing:
...
            else
            {
                _callingEntity = (Entity)_context.InputParameters["Target"];

                QueryExpression query = new QueryExpression("au_counterconfiguration");
                query.ColumnSet.AllColumns = true;

                query.Criteria = new FilterExpression();
                query.Criteria.AddCondition("au_entityname", ConditionOperator.Equal, _context.PrimaryEntityName);
                query.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);

                EntityCollection entityCollection = _orgService.RetrieveMultiple(query);
                if (entityCollection.Entities.Count == 0)
                {
                    throw new InvalidPluginExecutionException("Error: An Counter is configured for this entity although cannot locate the ID Generator config record.");
                }

               string entityid = string.Empty;
                //Key current entity = lock id
                string currentid = _context.PrimaryEntityId.ToString();

                //if lock key is equal then current key in process, then is record ready for writing
                while (entityid != currentid)
                {
                    //peridical checking, if record is free for processing
                    System.Threading.Thread.Sleep(25);
                    entityCollection = _orgService.RetrieveMultiple(query);
                    _counterEntity = entityCollection.Entities[0].ToEntity<au_counterconfiguration>();

                    entityid = _counterEntity.au_entityid;

                    //if entityid is empty, then record is free for processing. 
                    if (string.IsNullOrEmpty(entityid))
                    {
                        Entity updatedCounter = new Entity()
                        {
                            LogicalName = _counterEntity.LogicalName,
                            Id = _counterEntity.Id,                                
                        };
                        //only key value (entityid) will be saved, this key lock current record
                        updatedCounter["au_entityid"] = currentid;
                        _orgService.Update(updatedCounter);
                        _trace.Trace("Action: Locking configuration form with key {0}", currentid);                            
                    }
                }                    
            }

Finishing
__
               //set next number
                _counterEntity.au_NextNumber = new int?(Nextnumber.GetValueOrDefault() + Incrementby.GetValueOrDefault());

           //clean entity id (process is finished, the current record will be free)
                _counterEntity.au_entityid = null;                                

                //update counter entity
                _trace.Trace("Action: Update counter record");
                _orgService.Update(_counterEntity);   
...

__
Coordinator
Jun 4 at 4:22 PM
Thanks I will update the solution.