+ Start a Discussion
Apple88Apple88 

How to impose concurrent update control in controller extension?

Hi,

 

Sorry for the message I sent before displayed in a mess.  Hope this one looks better.  Below is the case:

 

When two users use the standard Edit page to edit the same record of a custom object at the same time, Force.com does control the concurrent update properly and display the error message as below when the second user tries to save his changes:

 

 

Your Changes Cannot Be Saved

The record you were editing was modified by Apple88 during your edit session.

Please re-display the record before editing again.

 

However, when I built a custom Visualforce page and override the standard Edit button of the custom object with the custom page, the custom page failed to manage the concurrent update properly.  Both users are able to retrieve and edit the same record at the same time, and able to save their changes successfully.  As the result, the changes made by the second user overwrite the changes of the first user without knowing.

 

Below is my custom page:

 

<apex:page standardController="Customer__c" extensions="CustomerEditCX"> <apex:variable var="CS" value="{!Customer__c}"/> <apex:sectionHeader title="Customer Edit" subtitle="{!CS.Name}"/> <apex:form > <apex:pageMessages ></apex:pageMessages> <apex:pageBlock mode="edit"> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!save}"/> <apex:commandButton value="Cancel" action="{!cancel}"/> </apex:pageBlockButtons> <apex:pageBlockSection > <apex:inputField value="{!CS.Name}" required="true"/> <apex:outputField value="{!CS.Status__c}"/> <apex:inputField value="{!CS.Number__c}"/> <apex:inputField value="{!CS.Owner__c}" required="true"/> </apex:pageBlockSection> <apex:pageBlockSection title="Contact Details"> <apex:inputField value="{!CS.Contact_Person__c}"/> <apex:inputField value="{!CS.Contact_Phone__c}"/> <apex:inputField value="{!CS.Fax_Number__c}"/> <apex:inputField value="{!CS.Mobile_Phone__c}"/> <apex:inputField value="{!CS.Corresponding_Address__c}"/> <apex:inputField value="{!CS.Email_Address__c}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

The above custom page use standard controller.  Not quite understand why it behaves differently from the standard Edit page? 

 

I have also tried to add a SOQL with "for update" option in the controller extension to lock the record.  However, it still failed to control the concurrency update properly.  Below is the controller extension:

 

public with sharing Class CustomerEditCX { Customer__c CS = new Customer__c(); public CustomerEditCX(ApexPages.StandardController StdController) { CS = (Customer__c)Stdcontroller.getRecord(); if (CS.ID != Null) { CS = [select Owner__c, Status__c from Customer__c where ID = :CS.ID for update]; system.debug('Supposed lock successfully: ' + CS.ID); } if (CS.Status__c == Null) { CS.Status__c = 'Draft'; } } }

 

Would anyone let me why the "for update" option does not work in the controller extension and how could we fix the problem?

 

Thanks for your help in advance.

 

Apple88

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

My understanding of "for update" is that it will only be locked for the duration of your transaction. Once your page has rendered, the transaction is over.  Otherwise malicious code could easily lock down whole organizations.

 

The easiest way to do this would be to capture the last modified date of the object where you are currently trying to lock it for update, and then when the user attempts to save, requery it and check if it has changed.  If it has, someone else has got hold of the record and changed it underneath you.