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
Drew1815Drew1815 

Apex Locking: FOR Update and Controller

I am trying to implement record locking within an Apex controller. To test this out, I have a very simple Visualforce page with a custom controller. In the controller's constructor I have a SOQL query that uses the FOR UPDATE keyword to lock the Account records queried. On page load, I want to lock the record so if another user access the same Visualforce page, record locking is enforced. The controller also has an action method to do a simple DML Update on the same account records that can be invoked through an apex command button. 

 

Here is my test scenario: I log in a 2 different users in different browsers, load the visualforce page which invokes the controller constructor. I then invoke the action method which performs the DML update. I was expecting to see the 2nd action fail since the first constructor invocation had locked the account records. But I was able to successfully update the account records. 

 

 

Question #1: How does Apex handle record locking across a controller's entire view state?

 

Question #2: Is there a way to lock a record for the duration of a Visualforce page where the SOQL is in the constructor but the DML operations are in other action methods within the same controller?  

 

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

I doubt you'll be able to lock records across transactions, which is effectively what you are attempting to do, once the page is rendered back to the browser, the transaction is complete..  Otherwise malicious code could lock down an entire organization with a few well chosen SOQL queries. 

 

Are you attempting to handle a race condition where two users update the same object, or is it something more complex?  If the former, then the way I'd do that is to capture the last modified date/time of the record into the controller and when the save method is executed, re-query that field and see if it has changed.  If it has, then somebody else got there first, so return an error and the latest version of the record to the user.

All Answers

bob_buzzardbob_buzzard

I doubt you'll be able to lock records across transactions, which is effectively what you are attempting to do, once the page is rendered back to the browser, the transaction is complete..  Otherwise malicious code could lock down an entire organization with a few well chosen SOQL queries. 

 

Are you attempting to handle a race condition where two users update the same object, or is it something more complex?  If the former, then the way I'd do that is to capture the last modified date/time of the record into the controller and when the save method is executed, re-query that field and see if it has changed.  If it has, then somebody else got there first, so return an error and the latest version of the record to the user.

This was selected as the best answer
Adu86Adu86
Hey Drew1815,

I have exact same situation that you described above. Could you please let me know how did you resolve that issue ?

Thanks