Unable to lock row - Record currently unavailable errors

ROW_LOCK issue is very common if you have multiple users updating the record at the same time .Or say a batch job is running and is updating a record and same record another trigger or code snippet (usually a future method) is updating.


Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE];
Using FOR UPDATE keyword helps to achieve a lock a client end to prevent this locking issues .

Assume there is an After Insert Apex Trigger on Tasks, and it runs for about 14 seconds while doing some processing. This trigger will run when a task is created. When tasks are created and are related to an Account, we place a lock on the parent Account while the task is being created. This means that the account cannot be updated while the task creation is in progress.

Scenario:
  1. 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.
  2. 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.
  3. 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.

The 2nd transaction then waits for the lock to be removed. Because the task takes about 14 seconds to be created, the lock is held for 14 seconds. The second transaction (from User B) times out, as it can only wait for a maximum of 10 seconds.

In this case, user B would see an error on the screen similar to the ones mentioned above. 

Bulk API 

Inserting or updating records through the Bulk API can cause multiple updates on the same parent record at once, because the batches are processed in parallel. For example, if two batches are being processed at the same time and the two of them contain records pointing to the same parent record, one of the batches will attempt to place a lock in the parent record, which can lead to the other batch throwing a "unable to lock row" error as the batch was not able to get a lock within 10 seconds.

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

For these type of scenarios, it's also highly recommended that you become familiar with the guidelines found on the article below

Post a Comment

0 Comments