In Apex, you can use FOR
UPDATE to lock sObject records while they’re being updated in order to prevent
race conditions and other thread safety problems.
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 client locking the records can perform logic on the records and make updates with
the guarantee that the locked records won’t be changed by another client during the lock
period. The lock gets released when the transaction completes.
To lock a set of sObject records in Apex, embed the keywords
FOR UPDATE after any inline SOQL statement. For example, the following statement, in
addition to querying for two accounts, 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 for
the lock to be released before acquiring a new lock. If the lock isn’t released within 10
seconds, you will get a QueryException. Similarly, if
you attempt to update a record currently locked by another client and the lock isn’t released
within 10 seconds, you will get a DmlException.
- If a client attempts to modify a locked record, the update operation might succeed if the
lock gets released within a short amount of time after the update call was made. In this case,
it is possible that the updates will overwrite those made by the locking client if the second
client obtained an old copy of the record. To prevent this 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
may have been previously executed.
- When you perform a DML operation on one record, related records are locked in addition to
the record in question. For more information, see the Record Locking Cheat Sheet.