FOR UPDATE will lock a row to prevent other clients from accessing it, as is well documented.

Does FOR UPDATE have an effect on pending inserts from concurrent clients as well?

For example, assume two clients, C1 and C2, concurrently doing:

  1. Select FOR UPDATE verifying that a specific row R does not exist
  2. Insert the specific row R

What is the expected outcome:

  1. C1 and C2 both fail fail to lock a row since the row does not exist. C1 and C2 both insert a specific row R.
  2. Atomicity and isolation (ACID) guarantee that one and only one client will successfully insert a specific row R. The other transaction will see the inserted row and thus not insert a duplicate.
  3. undefined
  • I think that as far the FOR UPDATE is part of a transaction no row R will be consider. FOR UPDATE affects mostly records that are in a SOQL query and when they are locked any attend to update those records will result in a message informing that there is a process running on those records and changes are not allowed. Inserting a new row, or record shouldn't be prevented as it doesn't conflict with the records that are part of the FOR UPDATE SOQL. – Carlos Naranjo Jan 30 '20 at 15:54
  1. undefined.

C1 and C2 cannot acquire a lock on a record that doesn't exist. To serialize access to a resource, they'd need to acquire a lock with FOR UPDATE on some "semaphore object" (like a Custom Setting, perhaps) that is guaranteed to exist.

If C1's transaction commits before C2 runs its SOQL query, or vice versa, the functionality will work as you expect. If not, however, it's a classic race condition and both clients may successfully commit.

To guard against concurrent inserts of duplicated records, some other functionality must be deployed, such as a uniqueness constraint on an External Id field or Duplicate Managementt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.