function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
tonantetonante 

Question Concerning UNABLE TO LOCK

Hi,
I have been getting a few  'unable_to_lock_row' exception when I  run Apex Test Execute  in Production or Sandbox  but when I execute  the test cases individually (unit test)  they pass.. Even a few of  the managed package test cases  fail due to this error.
A few of the local test classes all lock on the same object.

Since I have different  test classes that need to use this object to test different functionality, My Question is:

Q) Is there a way to avoid this error ?
Q) Would I have to do  some sort of asynchronization on the test cases in order for the cases to wait for until he object is free? If so, how do I do this?

 Thanks
Best Answer chosen by tonante
pconpcon
This comes from the fact that your test code likely uses the same "unique" identifiers in your test code.  For example if you had the following code to generate an account
 
public static Account createTestAccount() {
     Account acct = new Account(
          AccountNumber = '123456'
     );
     insert acct;

     return acct;
}

and then you used that code in all of your tests, you would likely run into UNABLE TO LOCK ROW errors because the AccountNumber is suppose to be unique and when there are updates happening on the account object it tries to lock that object but will fail because the external identifier is the same.

To work around this, you should create these external identifiers randomly and use those instead.  For example:
 
public static Integer getRandomInteger(Integer base) {
     return Math.round(Math.random() * base);
}

public static Account createTestAccount() {
     Account acct = new Account(
          AccountNumber = String.valueOf(getRandomInteger(100000)
     );
     insert acct;

     return acct;
}

If you are not using a TestUtils [1] type class to generate your testing data, I would recommend doing it.  This way you would just have to update it in one place instead of all of your tests

[1] http://pcon.github.io/presentations/testing/#testutils-intro

All Answers

pconpcon
This comes from the fact that your test code likely uses the same "unique" identifiers in your test code.  For example if you had the following code to generate an account
 
public static Account createTestAccount() {
     Account acct = new Account(
          AccountNumber = '123456'
     );
     insert acct;

     return acct;
}

and then you used that code in all of your tests, you would likely run into UNABLE TO LOCK ROW errors because the AccountNumber is suppose to be unique and when there are updates happening on the account object it tries to lock that object but will fail because the external identifier is the same.

To work around this, you should create these external identifiers randomly and use those instead.  For example:
 
public static Integer getRandomInteger(Integer base) {
     return Math.round(Math.random() * base);
}

public static Account createTestAccount() {
     Account acct = new Account(
          AccountNumber = String.valueOf(getRandomInteger(100000)
     );
     insert acct;

     return acct;
}

If you are not using a TestUtils [1] type class to generate your testing data, I would recommend doing it.  This way you would just have to update it in one place instead of all of your tests

[1] http://pcon.github.io/presentations/testing/#testutils-intro
This was selected as the best answer
tonantetonante
pcon. I have one last quesiton:  This could also happen with managed package code too?  I have found after running Apex Test Executee that sometimes my local code gets snagged with this error from Non-Profit Starter pack or that two managed package test lock up with each other over an object they need to update too.  Thanks much for the first answer because that is exactly what I needed to know,
pconpcon
It most certianly can happen for managed packages too.  If they write their test data generation similarly then it would happen to them as well.