Saturday, September 16, 2023

How to handle UNABLE_TO_LOCK_ROW error in salesforce?

This is one of the most common error in salesforce which occurs when multiple users or processes are trying to access and modify the same record simultaneously. 

This can be handle by following the below best practices:

1) While performing bulk operations, consider breaking them into smaller batches. Smaller batches are less likely to encounter locking conflicts. You can make use of Bulk API or Batch Apex, to process large volumes of data in smaller, controlled batches. 

2) You can also make use of FOR UPDATE as shown below to lock sObject records. While an sObject record is locked, no other client or user is allowed to make updates either through code or the Salesforce user interface. The lock gets released when the transaction completes. 

The example queries for two accounts and also locks the accounts that are returned.

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

Locking Considerations:

While the records are locked by a client, the locking client can modify their field values in the database in the same transaction. Other clients have to wait until the transaction completes and the records are no longer locked before being able to update the same records. Other clients can still query the same records while they’re locked.

If you attempt to lock a record currently locked by another client, your process waits a maximum of 10 seconds for the lock to be released before acquiring a new lock. If the wait time exceeds 10 seconds, a QueryException is thrown. Similarly, if you attempt to update a record currently locked by another client and the lock isn’t released within a maximum of 10 seconds, a DmlException is thrown.

If a client attempts to modify a locked record, the update operation can succeed if the lock gets released within a short amount of time after the update call was made. In this case, it’s possible that the updates overwrite those made by the locking client if the second client obtained an old copy of the record. To prevent the overwrite from happening, the second client must lock the record first. The locking process returns a fresh copy of the record from the database through the SELECT statement. The second client can use this copy to make new updates.

The record locks that are obtained in Apex via FOR UPDATE clause are automatically released when making callouts. Use caution while making callouts in contexts where FOR UPDATE queries could have been previously executed.

3) You can also implement a retry mechanism in your code so that when this error occurs, you can catch the exception, wait for a short period, and then try the operation again. 

Integer maxAttempts = 3;

Integer retryInterval = 2000; // 2 seconds

 

for (Integer attempts = 0; attempts < maxAttempts; attempts++) {

    try {

        // Perform the operation that might cause UNABLE_TO_LOCK_ROW

        // ...

        // If successful, break out of the loop

        break;

    } catch (Exception e) {

        if (e.getMessage().contains('UNABLE_TO_LOCK_ROW')) {

            // Wait for a moment before retrying

            Thread.sleep(retryInterval);

        } else {

            // Handle other exceptions as needed

            throw e;

        }

    }

}

No comments:

Post a Comment