You need to sign in to do that
Don't have an account?
tonante
Question Regarding KB 000199485 - Trigger Recursion
HI I just needed clarification on this solution that I made to the KB and wondered if I am understanding the action involved (semaphore?).
Before using the code in this solution I would have trigger recursion where one trigger process called a multiple number of times when it fired, For example: trigger Registration( which fires when Account is being inserted or before the acocunt is updated) would fire 10 times when Contact After Update trigger is fired once but there are 4 other triggers (i don;t have all their file names) that fire only once. This wastes time and uses unwanted resources. When I used the KB solution 000199485 above I noticed, while looking at the debug log system.debug statements, that the Registration trigger fires only once (which is good) but the other 4 triggers don't get to run. To solve this , I set the static boolean flag - firstRun - to true after the Trigger's IF Conditional has been executed by making a call to isResetRun() method. Therefore when I re-fire the Contact After Update trigger , all the trigger processes fire once per trigger and no more because they got permission when the
firstRun flag was reset to true otherwise the other triggers would still see the flag as false and quickly exit.
Q) Is this the correct/intended result? Here is a code sample of what I meant and pay special attention to the
checkRecursive.isResetRun() method call which I added to the KB solution code:
The Class Code for the Semaphore used in the KM solution I changed slightly by adding a method called
isResetRun:
Thanks for your help, comments, and questions. I just want to make sure that either I fixed the KB or if I have accidentally created any additional problems for myself . Again, with my solution the 4 trigger processes only fire once after a contact has been updated.
Before using the code in this solution I would have trigger recursion where one trigger process called a multiple number of times when it fired, For example: trigger Registration( which fires when Account is being inserted or before the acocunt is updated) would fire 10 times when Contact After Update trigger is fired once but there are 4 other triggers (i don;t have all their file names) that fire only once. This wastes time and uses unwanted resources. When I used the KB solution 000199485 above I noticed, while looking at the debug log system.debug statements, that the Registration trigger fires only once (which is good) but the other 4 triggers don't get to run. To solve this , I set the static boolean flag - firstRun - to true after the Trigger's IF Conditional has been executed by making a call to isResetRun() method. Therefore when I re-fire the Contact After Update trigger , all the trigger processes fire once per trigger and no more because they got permission when the
firstRun flag was reset to true otherwise the other triggers would still see the flag as false and quickly exit.
Q) Is this the correct/intended result? Here is a code sample of what I meant and pay special attention to the
checkRecursive.isResetRun() method call which I added to the KB solution code:
trigger AccountAfterUpdate on Account (after update) { if(checkRecursive.isFirstRun()){ // To avoid the recursion on trigger One Trigger Per Object Integer acctLimit = Trigger.new.size(); List<Account> UpdateAccountList = new List<Account>(); List<Account> UpdateRegLevelList = new List<Account>(); List<ID> acctIDs = new List<ID>(); List<Account> clonedAccounts = new List<Account>(); Account modifiedAccount; Account clonedAccount; List<RecordType> getPersonRecordType = [Select Id from recordType where Name = 'Individual_Person']; List<RecordType> getUSRecordType = [Select Id from recordType where Name = 'US Organization']; List<Account> OtherAccounts = new List<Account>(); //non-PMM Account tasks. //1. See if its PMM value has changed for Account records. for(Integer aCnt = 0; aCnt < acctLimit; aCnt++){ //A. <<For Address Synchronization:>> // See if Address have been updated for Person Accounts if(Trigger.new[aCnt].RecordTypeId == getPersonRecordType[0].Id){ if(Trigger.new[aCnt].ShippingStreet != Trigger.old[aCnt].ShippingStreet || Trigger.new[aCnt].ShippingCity != Trigger.old[aCnt].ShippingCity || Trigger.new[aCnt].ShippingState != Trigger.old[aCnt].ShippingState || Trigger.new[aCnt].ShippingCountry != Trigger.old[aCnt].ShippingCountry || Trigger.new[aCnt].ShippingPostalCode != Trigger.old[aCnt].ShippingPostalCode || Trigger.new[aCnt].BillingStreet != Trigger.old[aCnt].BillingStreet || Trigger.new[aCnt].BillingCity != Trigger.old[aCnt].BillingCity || Trigger.new[aCnt].BillingState != Trigger.old[aCnt].BillingState || Trigger.new[aCnt].BillingCountry != Trigger.old[aCnt].BillingCountry || Trigger.new[aCnt].BillingPostalCode != Trigger.old[aCnt].BillingPostalCode ){ modifiedAccount = Trigger.new[aCnt]; clonedAccount = new Account(Id=modifiedAccount.Id, Physical_Street_1__c =modifiedAccount.BillingStreet, Physical_City__c = modifiedAccount.BillingCity, Physical_Zip__c = modifiedAccount.BillingPostalCode,Physical_State__c = modifiedAccount.BillingState, PhysicalCountry__c = modifiedAccount.BillingCountry,Mailing_Street_1__c = modifiedAccount.ShippingStreet, Mailing_City__c = modifiedAccount.ShippingCity,Mailing_State_Province__c = modifiedAccount.ShippingState, Mailing_Zip_Postal_Code__c = modifiedAccount.ShippingPostalCode,Mailing_Country__c = modifiedAccount.ShippingCountry); clonedAccounts.add(clonedAccount); } } //B.<<For Team Member Manager:>> Check to see if the Owner Id has changed on US Organizations if(Trigger.new[aCnt].RecordTypeId == getUSRecordType[0].Id){ //11-23-2014 Added conditional using Record Type as a flag to process for US Orgs only. if(Trigger.new[aCnt].OwnerId != Trigger.old[aCnt].OwnerId && (Trigger.new[aCnt].OwnerId != null && Trigger.old[aCnt].OwnerId != null) ){ // This should never happen for Person Accounts. UpdateAccountList.add(Trigger.new[aCnt]); acctIDs.add(Trigger.new[aCnt].Id); }//IF }//IF }// FOR //2. <<For Team Member Manager:>> Displatch for processing which accounts .. if(UpdateAccountList.size() > 0){ system.debug('<<TMACCTS>> '+UpdateAccountList); TeamMemberAccounts.handler(UpdateAccountList,acctIDs); } //3. <<For Address Synchronization on Person Accounts:>> if(clonedAccounts.size() > 0 ){ update clonedAccounts; system.debug('*** New ACCOUNT ID *** '+clonedAccounts[0].Id+' *** New ACCOUNT Mailingn Address *** '+clonedAccounts[0].Mailing_Street_1__c+' *** New ACCOUNT PhysicalAddress *** '+clonedAccounts[0].Physical_Street_1__c); } }// checkRecursion // Before leaving, give 'key' to the next available trigger to unlock critical section for Access. checkRecursive.isResetRun(); // <------------ KB Class Update. Free up the firstRun'key' . }
The Class Code for the Semaphore used in the KM solution I changed slightly by adding a method called
isResetRun:
public class checkRecursive{ private static boolean firstRun = true; public static boolean isFirstRun(){ if(firstRun){ firstRun = false; return true; }else{ return firstRun; } } public static boolean isResetRun(){ // <------------ New method to free up the 'key' firstRun firstRun = true; return true; } }// checkRecursive
Thanks for your help, comments, and questions. I just want to make sure that either I fixed the KB or if I have accidentally created any additional problems for myself . Again, with my solution the 4 trigger processes only fire once after a contact has been updated.
Note: - The static variable will hold the value only in that execution context, after that it will automatically reset to the initally value as true.