How to Resolve Unable to lock row error in Salesforce
When a record is being updated or created, Salesforce places a lock on that record to prevent another operation from updating the record at the same time and causing inconsistencies on the data.
Record locking errors is a common source of headache for people coding Data Migrations or Integrations with Salesforce. The good news is that most of the time It's our own integration code that is causing self-contention as opposed to some other user locking the record on us (because we are plowing too many conflicting updates at once, usually in an effort to improve performance). It can also be caused by Salesforce code that is triggered by our updates that require the locks, and then, when not getting them, ultimately fail. Then, that error bubbles up and our updates fail.
Lets walk through an example:
- User A imports a task via the data loader and assigns it to an existing account record. When the task is inserted, the apex trigger is fired.
- Just 2 seconds after User A starts the insert via the data loader, User B is manually editing the same account record the task is related to.
- When User B clicks Save, internally we attempt to place a lock on the account, but the account is already locked so we cannot place another lock. The account had already been locked by the creation of the Task.
To prevent this, you can do either of the following:
- Reduce the batch size
- Process the records in Serial mode instead of parallel, that way one batch is processed at a time.
- Sort main records based on their parent record, to avoid having different child records (with the same parent) in different batches when using parallel mode.
- Check for overlapping schedules, 2 schedules updating the same object should not start at the same time if possible.