[SalesForce] Unlocking and locking a record in approval process in one Transaction

In this scenario I have two object Foo__c and zoo__c. Whenever a particular field in Foo__c is updated it should update certain fields in zoo__c object.

My problem : Some of the zoo__c records can be in approval process and hence locked. This gives an error saying record is locked.

Solution that I think will work: In my transaction where I update the zoo__C record when Foo__c record's field is updated, I can use isLocked(id) method to check whether the record is locked and unlock it using unlock(recordId). After I update the fields of zoo__c I can lock it again.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_approval.htm

My concern – "Governor limits"

On a high level I have two options to unlock,update,lock back the records:

1.

        `List<zoo__c> zoolist = [select id from zoo__c]; // this can have locked and unlocked records, depending on the records approval process`

            // first unlock only the records in the list that are locked and then iterate
            // I do not know the exact syntax but can this be used - unlock(recordToUnlock). It return a type Approval.UnlockResult so I am not sure how I can get List(unlockedzooList) out of it that I can Iterate:

             For(zoo__c z : unlockedzooList){
               // do the operation
               updatezooorecordList.add(z);
              }

              For(zoo__c z : normalrecords){
               // do the operation
               updatezooorecordList.add(z);
              }

            update updatezooorecordList;

        // Now lock only those records back again which were unlocked(unlockedzooList)- using `Approval.LockResult lock(SObject recordToLock)`
  1. I can check while iterating in the for loop whether the records is locked or unlocked and take appropriate action:

code

List zoolist = [select id from zoo__c];
List<zoo_c> toLockagainList = new List<zoo__c>();
For(zoo__c z : zoolist){ 
if(isLocked(z.id){
unlock(z.id);
toLockagainList.add(z);
}
// do the operation 
}
updatezooorecordList.add(z); 

// Lock those records back which were unlocked in For loop.
For(zoo__c z : toLockagainList){ 
lock(z.id);
}

Note :- there could be 200 records which has to go through this operation in one transaction. Is there any governor limits hit in here or any performance issues?

My first option implementation may not be so clear as I haven't figure out the syntax of locking and unlocking only the list of records which were locked in first place. Which option do you propose?

Best Answer

On doing some research on my own I found that Option 1 of my questions should be the way to unlock and lock the records as it will avoid hitting the governor limit. The option 2 will definitely hit the governor limit as it is checking the each record whether it is locked or not and then making it unlock. It consumes 1 DML to unlock or lock a record.

I choose below method to unlock the records.

public static List<Approval.UnlockResult> unlock(List<SObject> recordsToUnlock, Boolean allOrNothing)
Related Topic