March 9, 2015

Concurrent access and race condition in Salesforce on insert operation

Assume you have some VisualForce page with complex logic which also has to create some custom object record if it does not exist for current user and current month or even for current day. Is there any possibility to prevent concurrent record insertion like race condition in Salesforce?

First thought that comes to mind is just to check if record does not exist just before record insertion so it should prevent from any duplication happening. However, in a real world situation it may not help if the same user opens the same page in two tabs or browsers and it happens that in both cases record does not exist just before insert\upsert operation, so a duplicate record is still created like it is shown on this picture

RaceConditionConcurrentInsert

Salesforce provides built-in keyword ‘for update’ if you want to make thread-safe update operation. If Salesforce locks records when update operation happen, so you may see error like “UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record”. I have seen this error many times during tests execution, it happens when some unit test tries to touch some record which is locked by another unit test or user. However, this does not really help in insert or upsert operation when your goal is to prevent duplicate record insertion.

There is still a solution.

You need to create some new unique text field on the custom object you want to prevent from duplicated record insertion or you can mark as unique some of the existing text field which should be unique and would uniquely identify the record.

For my case I have created Unique Key field

1
2
3
4
5
6
7
8
9
10
11
12
13
<fields>
    <fullName>Unique_Key__c</fullName>
    <caseSensitive>false</caseSensitive>
    <description>Unique Key to prevent duplication of records on 
concurrent insert\race condition</description>
    <externalId>false</externalId>
    <label>Unique Key</label>
    <length>255</length>
    <required>false</required>
    <trackFeedHistory>false</trackFeedHistory>
    <trackHistory>false</trackHistory>
    <type>Text</type>
    <unique>true</unique>
</fields>

on both custom object definitions where I wanted to prevent duplicated records insertion.
Also I had to create trigger on both of my custom objects and introduce new method which would populate Unique Key field and would be called from before insert trigger

1
2
3
trigger MyCustomObjectTrigger on My_Custom_Object__c (before insert) {
    MyCustomObjectServices.populateUniqueKey( Trigger.new );
}
1
2
3
4
5
6
7
public static void populateUniqueKey(List<My_Custom_Object__c> objects){
    for ( My_Custom_Object__c o: objects) {
        Date day = o.My_Custom_Date_Field__c;
        
        o.Unique_Key__c = day.day() + '_' + day.month() + '_' + day.year() + '_' + ts.My_Custom_Lookup_To_User_Field__c;
    }
}

Both of My_Custom_Date_Field__c and My_Custom_Lookup_To_User_Field__c should be marked as required to be able to populate Unique Key field in before insert trigger.

Also I had to change implementation of my page controller extension so show appropriate error message for users who do not understand what is concurrent access and race condition

1
2
3
4
5
6
7
8
9
10
try {
     upsert myCustomObjectList;
} catch ( Dmlexception dmle ){
    String errorMessage = dmle.getDmlMessage( 0 );
    if ( StatusCode.DUPLICATE_VALUE == dmle.getDmlType( 0 ) ) {
        errorMessage = 'Looks like you are trying to perform this logic from multiple tabs or browsers simultaneously. Operation failed.';
    }
    ApexPages.addMessage( new ApexPages.Message( ApexPages.Severity.ERROR, errorMessage ) );
    return;
}

I hope you enjoyed reading this post and found something useful and learned something new.

You may click like to let me know that you did really enjoy 🙂

Tags

Technical

Share


Recent Articles

More Value with Lightning Value Providers

February 15, 2019 | Bohdan Dovhan, Senior Salesforce Engineer

Salesforce cloud platform offers the whole variety of customization options. Those include point-and-click tools like Lightning App Builder, Process Builder, Visual Flow and Workflow alongside development tools like Apex, Visualforce, Lightning Aura Components, Lightning Aura Events, Lightning Aura Tokens, Lightning Aura Standalone application and Lightning Web Components. Lightning Aura Components development involves the development of […]

Hot in Salesforce Marketing Cloud: January 2019 Release Notes

February 8, 2019 | Ihor Shupeniuk, Salesforce Engineer and Marketing Cloud Specialist

In the era of intelligent marketing with the proliferation of technology where modern consumers are offered the widest choice, Marketing Cloud is sometimes named a future-looking service, We continue to closely follow the developments and improvements to  Marketing Cloud and we can safely affirm that this product is becoming better and better. Everyone who has […]