function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Parsa MotamediParsa Motamedi 

unable to obtain exclusive access to this record or 1 records: 07H7Y000000Cc1RUAS - when running tests

I'm getting a peculiar error, something I haven't seen before, when I run test classes. All the failing tests were passing successfully earlier (a week ago).
System.DmlException: Insert failed. First exception on row 0; first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record or 1 records: 07H7Y000000Cc1RUAS: []
The 07H prefix refers to ContentFolder.

I get this error on some test classes where I refer to some Content- object. If I run these tests individually, some of them pass while some won't even pass if run them on their own.

I have one Library, which is the standard Assets Library. The error happens when I call insert on a list of ContentVersion records. I'm running these tests as System Administrator on our sandbox org.

How would I go about debugging this error?
Thanks in advance.
AbhishekAbhishek (Salesforce Developers) 
Hi,

Salesforce platform has a feature ROW LEVEL Security. This feature ensures that sharing and visibility set by salesforce administrators for the records have to be maintained. As a part of this feature, there are sharing calculations that the platform has to perform when the record ownership is changed or child records are created/modified.
 
  • Assume that a company’s salespeople are adding new contacts into an account. When they click Save, the database automatically locks the parent account when it begins the DML operation and before it actually inserts the Contact. The database releases the lock after executing the triggers and standard save operations. This scenario illustrates the locking that can occur in parent-child relationships
  • The next thing to understand is a side-effect known as parent implicit sharing. In a private sharing model, something else occurs when the Salesforce platform creates contact. The built-in implicit sharing feature provides record accessibility, and its parent implicit sharing provides read access to an account for users who have access to standard child objects, such as Contacts, Cases, and Opportunities.
  • So when salespeople create a Contact, sharing calculations determine during the save operation if a parent implicit share to the Account should be created. In this example, the calculations happen quickly. Assume that the salespeople have been very active and have created 300,000 child objects under a single generic account. They now have a skewed account.
  • If another salesperson tries to add a new contact for the same account while the sharing calculations are occurring, that request will wait for the Salesforce platform to release the lock on the account, resulting in lock contention and reduced database concurrency.


A record can also go into a Locked State if it is a parent and part of master-detail relationships and child records are getting saved/updated.


You can read how apex can prevent such locks using the link here (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_locking_records.htm).
 


Using FOR UPDATE keyword in SOQL helps to achieve a lock on a client end to prevent these locking issues.


Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE];


Here are some helpful articles on how to design your sharing model to avoid granular locking

https://help.salesforce.com/apex/HTViewSolution?urlname=How-can-I-avoid-getting-lock-errors-in-my-organization-1327109108393&language=en_US

http://blogs.developerforce.com/engineering/2013/01/reducing-lock-contention-by-avoiding-account-data-skews.html



You can prevent using the below techniques

  1. Make sure you have an optimized data model with no Data Skews (No more than 10K child records for a parent record)
  2. Make sure you do not have Ownership skews(No single owner owning lots of records when the private sharing model is turned on).
  3. Ask support if they can enable granular locking




Let me know if it helps you and close your query by marking it as solved so that it can help others in the future.

Thanks.
Parsa MotamediParsa Motamedi
Hello Abishek,
This is not something that requires edits to the Apex code to fix. As I've mentioned, these tests were passing last week. There has been a change elsewhere that is causing this. I need help to narrow down where to look to fix this error.