In spring13, I am getting UNABLE_TO_LOCK_ROW error in my few test classes while running all test classes in new view provided in spring13 release. But in winter12 I don't get any error like this. Do I have to do anything to make it work? Any Thoughts?

  • Are your tests relying on data that exists in the environment? @seeAllData=true or API version below 24? You should aim at making the test data in the test itself, even if it's a test that uses System.runAs(user u)... What happens if you run them all from Eclipse? Might be something nasty to do with server load/parallel execution. – eyescream Feb 5 '13 at 9:56
  • When I run test classes separately which gave me error while running all tests together now they pass. – doga Feb 5 '13 at 10:07
up vote 15 down vote accepted

I have gotten this error before this release. In our particular scenario, the organization had a pre-existing Custom Setting that essentially held an auto-incrementing number as an external ID for an account. The reason this error would happen every so often is due to the fact that some of the unit tests were old and using the old API. The problem came when these tests ran asynchronously and would both attempt to update this Custom Setting at the same time. This would cause the UNABLE_TO_LOCK_ROW error you are seeing since one class already had the DB lock on it. To fix this particular issue, we updated the old tests to properly create their own instance of the Custom Setting.

The error was rather strange to figure out, because just as you are seeing, the tests were very random in that they would work sometimes and other times they would fail dramatically.

Now, the scenario I outlined above is only one instance. This type of error can be thrown when two classes try to update any of the same object. If you have old code that both pull a contact from the DB for instance for testing, they can fail because of this same issue.

To fix this issue you need to go through your failing unit tests and make sure none of them use existing data from the database. You should be recreating the data model every time a test runs. It is highly inefficient, but it is the best practice for now until mocks are introduced (I am hoping those come as soon as possible). So, just make sure you never expect data in the database. Always create your own within the context of your unit test.

  • 1
    ... and if you really really have to rely on existing data - at least use [SELECT ... FOR UPDATE] ;) – eyescream Feb 5 '13 at 17:55
  • We are getting this too. Sometimes we can't or don't want to create our own data (that seeAllData attribute is there for a reason). Using locking (FOR UPDATE) works for a couple tests, but if you have several tests running at once that access the same records, it is still a problem. I guess there's no way to have a test not run in parallel with others? – Rob Scott Feb 6 '13 at 20:02
  • 1
    @RobScott - You can run them synchronously from the Apex Test Executioner. When you deploy it should be synchronous. See page 110 of the Spring '13 Release Notes. Still, if someone in the org does something at the same time as the unit test it could be an issue, I suppose. – Peter Knolle Feb 15 '13 at 2:21
  • 2
    I'm seeing this also with custom settings, but with tests that are marked SeeAllData=false. Surely these should be isolated from each other? – Richard Corfield Aug 23 '13 at 9:54

I've run into this as well in the past. When run individually the test classes all pass, but when run in parallel they fail.

Jesse's answer is a better long term option as it will resolve the underlying issue.

As a short term fix you can Disable Parallel Apex Testing.

Your Name > Setup > Develop > Apex Test Execution > Options: Disable Parallel Apex Testing

Update Summer '17

The Summer '17 release (v40.0) adds a new isParallel=true annotation to @isTest that provides the bypass for disabled parallel testing to enable it on a test class by test class basis again.

See New Option for Parallel Testing on the isTest() Annotation

Use the @isTest(isParallel=true) annotation to indicate test classes that can be run in parallel and aren’t restricted by the default limits on the number of concurrent tests. This makes the execution of test classes more efficient, because more tests can be run in parallel.

This annotation overrides settings that disable parallel testing by default. A test class that doesn’t have this annotation is restricted by the default limits on the number of concurrent tests.

Note that I attempted to use @IsTest(isParallel=false) in a pre-release org. It didn't appear to work. Source

Update on Update Summer '17

From the Release Notes Changes 10th May 2017

Withdrawn New Option for Parallel Testing on the isTest() Annotation The isParallel option on the isTest() annotation is not available in this release. The release note about the option was removed.

Update on Update Winter '18

Run Parallel Tests Using a New Option on the @isTest Annotation is back in Winter '18.

I've also added the idea Parallel Tests Option (isParallel) on the @IsTest Annotation to exclude tests.

  • Will this also stop asynchronous unit tests from running when you do a deploy? As far as I know, all unit tests run asynchronously during a deploy no matter what you do. – Jesse Altman Feb 15 '13 at 3:12
  • @JesseAltman You can still run the test cases asynchronously, but they will run one at a time. By default I think two tests run in parallel with asynchronous testing, which is where the issue occurs. – Daniel Ballinger Feb 15 '13 at 7:39
  • 1
    Maybe we could update this answer after Summer17 is released: releasenotes.docs.salesforce.com/en-us/summer17/release-notes/… – Christian Szandor Knapp Apr 25 '17 at 18:44
  • 1
    @ChristianSzandorKnapp Done. Perhaps the bigger outstanding question is if @IsTest(isParallel=false) is something that is supported to disable parallel testing at a more selective level. – Daniel Ballinger Apr 25 '17 at 22:15
  • 1
    @DanielBallinger Thanks, I noticed the idea today before I even read this comment! And I voted, of course ;) – Legolas Oct 6 '17 at 19:01

We also face the same issue time to time. We pinpointed our error to inserting test users in Unit Test Classes. Since we are copying the Test User data from class to class, user names of those test user are same across different classes, and when these test classes execute in parallel, inserting two users with same user name was causing the issue. We were able to fix our test classes once we adjusted the user name.

This is from documentation . Probable cause -

  • When tests update the same records at the same time. Updating the same records typically occurs when tests don’t create their own data and turn off data isolation to access the organization’s data.
  • When a deadlock occurs in tests that are running in parallel and that try to create records with duplicate index field values. Test data is rolled back when a test method finishes execution. A deadlock occurs when two running tests are waiting for each other to roll back data, which happens if two tests insert records with the same unique index field values in different orders.

Try running it with "Disbale Parallel Running" in Options as true. It will work

One possible cause for this is using Test.getStandardPricebookId in a test. This idea asks salesforce to fix that bug.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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