Wednesday, December 14, 2011

Prevent Recursion of Trigger Execution in Salesforce - Part1




Salesforce – Prevent Recursion of Trigger Execution <Method-1>


Suppose there’s a scenario where in one trigger perform update operation, which results in invocation of second trigger and the update operation in second trigger acts as triggering criteria for trigger one. In that case there will be a recursion and then it will result the Apex Governor Limits Errors .. 

Following are two methodology which helps to control of multiple triggers and prevent recursion.

Method -1

  • Use a static variable to store the state of the trigger processing.
  • Use @future method. The only thing we need to add is one line of code to set the isFutureUpdate variable to true before we perform the update operation.

Method-2

  • Add a new field to the object so the trigger can inspect the record to see if it is being called by the future method.

Method:(1)  Use a static variable to store the state of the trigger processing. & Use @future Method to Restrtict the recursive call of the trigger

Apex Controller:

The shared FutureUpdateController  class with the static variable that is shared by the trigger and used to determine when to exit the process.

public class FutureUpdateController{

    public static boolean isFutureUpdate = false;

}

Here is the trigger, we only want the code in this trigger to execute if the isFutureUpdate variable is not true.


trigger updateSomething on Account (after insert, after update) {

    //execute when the update is not from an @future method
    if(FutureUpdateController.isFutureUpdate != true){
        
         Set<Id> idsToProcess = new Se<Id>();
         for(Account acct : trigger.new){
            if(acct.NumberOfEmployees > 500){
                idsToProcess.add(acct.Id);
            }
        }
         //Send Ids to @future method for processing
        FutureMethodsProcessor.processAccounts(idsToProcess);
     }
}

Here is the  @future method. The only thing we need to add is one line of code to set the isFutureUpdate variable to true before we perform the update.
Now when the trigger is fired , the @future method will not be called again.

public class FutureMethodsProcessor{
     @future
    public static void processAccounts(Set<Id> IDs){

         // list to store the accounts to update
          List<Account> accountsToUpdate = new List<Account>();
         
          // iterate through the list of accounts to process
          for (Account a : [Select Id, Name, IsFutureExecute__c From Account where ID IN :IDs]) {
               
               // add the account to the list to update
               accountsToUpdate.add(a);
          }

        //Before we perform this update we want to set the isFutureUpdate boolean in our utility class   to true 
       
        FutureUpdateController.isFutureUpdate = true;
         //Now we can perform the update. The trigger will still fire but none of the code inside of it will execute 
        update accountsToUpdate;

    }
}In my next Post , I will explain about the Method-2 to prevent  recursion in trigger execution.