+ Start a Discussion
Miranda L 2Miranda L 2 

UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record: []

Hello there,
my batch getting failed to update some records and I gets following error message.
Apex script unhandled exception by user/organization: 0098d000007tvRV/00Db002ef00HO6N

Failed to process batch for class 'CalcFirstInvoice' for job id '7070X5640CQtuKf'

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

Class.CalcFirstInvoice.execute: line 26, column 1

Please help me
Miranda L 2Miranda L 2
here is my apex Batch class
global class CalcFirstInvoice implements Database.Batchable<sObject>,Schedulable {
    
    String query = 'SELECT id,(SELECT Date_Invoice__c FROm Invoices__r WHERE Date_iNVOICE__C!=null AND Category_Invoice__c !=\'Monthly\' ORDER BY Date_Invoice__c ASC LIMIT 1),First_Invoice__c FROM Account';
    
    global CalcFirstInvoice() {
        
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext BC, List<sObject> scope) {    
        List<Account> toUpdate = New List <Account> ();
        for(Account A: (List<Account>) scope) {
            if(!A.Invoices__r.isEmpty()){
                A.First_Invoice__c = A.Invoices__r[0].Date_Invoice__c;
                toUpdate.add(A);
            }
            //if Invoice empty then update First Invoice as empty 
            if(A.Invoices__r.isEmpty()){
                A.First_Invoice__c=null;
                toUpdate.add(A);
            }
        }
        update toUpdate;
    }
    
    global void finish(Database.BatchableContext BC) {
        
    }
    public void execute(SchedulableContext context) { 
        Database.executeBatch(this);
    }
    
}

Thank you
mukesh guptamukesh gupta
Hi Miranda,

When two users or two different apex code tries to update the same record, then salesforce throws an error “UNABLE_TO_LOCK_ROW unable to obtain exclusive access to this record”.

Using FOR UPDATE keyword helps to achieve a lock a client end to prevent this locking issues.
List<Account> accountList = [SELECT Id FROM Account FOR UPDATE];

in your code you use below line:-
 
String query = 'SELECT id,(SELECT Date_Invoice__c FROm Invoices__r WHERE Date_iNVOICE__C!=null AND Category_Invoice__c !=\'Monthly\' ORDER BY Date_Invoice__c ASC LIMIT 1),First_Invoice__c FROM Account LIMIT 2 FOR UPDATE';



Here is an article.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_locking_statements.htm

If this solution is usefull for you, Please mark as a Best Answer to help others.


Regards
Mukesh