Im getting the following error:
caused by: System.QueryException: Record Currently Unavailable: The record you are attempting to edit, or one of its related records, is currently being modified by another user. Please try again.
This happens on the first line of the calculatePAKPIOnSoldprotocol
method which is called by the calculatePAKPIOnSoldprotocolAsync
future method.
I understand this is a locking issue.
- Calling an apex class from a future method I suppose the context still future right?
- Do I need to remove the FOR UPDATE since its interfering with another for FOR UPDATE or am I missing something else?
if(!protocolIds.isEmpty()) {
if (System.isFuture() || System.isBatch()) {
calculatePAKPIOnSoldprotocol(protocolIds);
}
else {
calculatePAKPIOnSoldprotocolAsync(protocolIds);
}
}
@future
private static void calculatePAKPIOnSoldprotocolAsync(Set<Id> scopeIds) {
calculatePAKPIOnSoldprotocol(scopeIds);
}
private static void calculatePAKPIOnSoldprotocol(Set<Id> scopeIds) {
List<Sold_protocols__c> scope = [SELECT Id, TNT_Nr_proposed_Pas_Applications__c, TNT_Total_Pas_Application_on_protocol__c, (SELECT Id, cxsrec__Status__c FROM Pas_Applications__r) FROM Sold_protocols__c WHERE Id IN: scopeIds FOR UPDATE];
Map<String,Integer> packPACountMap = new Map<String,Integer>();
Map<String,Integer> packPAProposedMap = new Map<String,Integer>();
UpdateCounterKPIprotocol.calculateProposedAndCount(packPACountMap, packPAProposedMap, scope);
List<Sold_protocols__c> spToUpdate = new List<Sold_protocols__c>();
for (Sold_protocols__c pack : scope){
if(pack.TNT_Nr_proposed_Pas_Applications__c != packPAProposedMap.get(pack.Id) || pack.TNT_Total_Pas_Application_on_protocol__c != packPACountMap.get(pack.Id)) {
pack.TNT_Nr_proposed_Pas_Applications__c = packPAProposedMap.get(pack.Id);
pack.TNT_Total_Pas_Application_on_protocol__c = packPACountMap.get(pack.Id);
spToUpdate.add(pack);
}
}
if(!spToUpdate.isEmpty())
update spToUpdate;
}
UpdateCounterKPIprotocol
does a callout, the For Update lock is released and needs to be re-acquired. Switch the future to queueable and if you get the error, chain a new queueable