11

We're receiving the:

caused by: System.DmlException: Insert failed. First exception on row 0; first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record: []

exception in some of our customer orgs. Does anyone know of a fairly reliable way to trigger this error so I can test fixes for it?

5
  • 2
    Dan Appleman gave a presentation on Dreamforce last year on this topic, in the presentation if I remember correctly he also provided some code to reproduce it. This is also covered in his book "Advanced Apex Programming – 2nd edition" advancedapex.com youtube.com/watch?v=AK9m8E5wwts
    – PepeFloyd
    Commented Jul 11, 2014 at 12:15
  • 1
    Here was his slide, though it doesn't have the logic to reproduce it... slideshare.net/developerforce/concurrency-designpatterns-mt
    – Double A
    Commented Jul 11, 2014 at 12:57
  • this could either be caused by conflicting DML operations in the various trigger execution or some recursive trigger execution. i would assume that the async executions cause multiple subsequent updates on the same records. I would recommend to try to simplify the process to avoid too many related trigger executions. Plz go through the below link may be it will help to resolve your problem click here Commented Jul 11, 2014 at 14:56
  • In a test method, it's impossible, because you need more than one simultaneous transaction (even batches, etc are considered in the same transaction in a test method), but you certainly can trigger that exception with 100% accuracy. I did so in this question to determine how much leeway you have before a transaction fails due to row locks. I don't know if this will help you, though... (Summary) make VF page with two remote actions. Call both at once.
    – sfdcfox
    Commented Jul 12, 2014 at 17:13
  • Thanks to @PepeFloyd. I've managed to reproduce the error now, using the code given in the video. It's a long video so for anyone else, the code is about 18 mins in.
    – Jess
    Commented Jul 14, 2014 at 16:15

2 Answers 2

4

You will need a technique for creating multiple concurrent requests for processing against the same record that is locked using FOR UPDATE.

One option is to use the @future annotation to queue up multiple concurrent requests that will retrieve a single record using FOR UPDATE in the SOQL call. If you can get these methods executing for long enough you will start getting UNABLE_TO_LOCK_ROW errors as transactions timeout waiting for the exclusive lock.

From anonymous apex you can make several calls to the future method to get them running at the same time.

You will need to create some form of busy operation to keep the record locked for more than 5 seconds (but less than 10 seconds). This could be a simple a for loop that counts from 0 to some very large number. You will need to experiment with the large number to get the required timing.

0

I know this post is a bit aged and my response is going to sound quite obvious but I just came across this as I am debugging this specific concurrency problem so:

Follow the stack trace to any user input interface (could be a record detail page)

Alternatively, ask the user what they were doing when the error popped up. (If it's a large organization they would set up and communicate a protocol to report this errors along with repro steps that could pass on to the support team).

Once you identify such user input interface: on a full (or partial) copy sandbox, open two tabs on the browser of your preference, do whatever the user was doing on two different records and save as concurrently as you can.

The whole craft described, assumes some user interaction is involved in the error being triggered. If it is a product of something else (API call, batch job, etc) it renders futile :)

Finally here is a screen shot of my successful execution of the above technic (disclaimer: all labels, the product and a class name are in Spanish): enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .