Recursive triggers in Salesforce

     You want to write a trigger that creates a new record as part of its processing logic; however, that record may then cause another trigger to fire, which in turn causes another to fire, and so on. You don't know how to stop that recursion.
     Use a static variable in an Apex class to avoid an infinite loop. Static variables are local to the context of a Web request (or test method during a call to runTests()), so all triggers that fire as a result of a user's action have access to it.

Example:
     Suppose there is 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.

Solution:

Class:

public class Utility
{
    public static boolean isFutureUpdate;
}


Trigger:

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

    /*  This trigger performs its logic when the call is not from @future */
    if(Utility.isFutureUpdate != true)
    {

        Set<Id> idsToProcess = new Se<Id>();

        for(Account acct : trigger.new)
        {
            if(acct.NumberOfEmployees > 500)
            {
                idsToProcess.add(acct.Id);
            }
        }

        /* Sending Ids to @future method for processing */
        futureMethods.processLargeAccounts(idsToProcess);

    }
}


Class:

public class FutureMethods
{

    @future
    public static void processLargeAccounts(Set<Id> acctIDs)
    {

        List<Account> acctsToUpdate = new List<Account>();

        /* isFutureUpdate is set to true to avoid recursion */
        Utility.isFutureUpdate = true;
       
        update acctsToUpdate;
    }
}


Cheers!!!

4 comments:

  1. nice programming.........

    ReplyDelete
  2. I am not getting the value of potential in this program can any crack this error?
    the previous program i am getting error too many future call 11.like this i am getting the error while deploying .then i converted my code in this way .it is not calculating the potential value. can you crack it where it went wrong?



    Trigger :

    trigger quotepotential on Quote_Line_Item__c (after insert, after update) {
    if(System.isFuture()) {
    return;
    }
    asyncApex.processAccounts(Trigger.newMap.keySet());
    }

    class :

    global class asyncApex {
    @future public static void processAccounts(Set quoteIds) {
    Map quotes = new Map();
    for(Id quoteId: quoteIds) {
    quotes.put(quoteId, new Quote__c(Id=quoteId, Potential__c=0.0));
    }
    for(AggregateResult ar:[SELECT Quote1__c Id, SUM(Max_Batch__c) sumMax FROM Quote_Line_Item__c WHERE Quote1__c IN :quoteIds GROUP BY Quote1__c]) {
    quotes.get((Id)ar.get('Id')).Potential__c = (Decimal)ar.get('sumMax');
    }
    update quotes.values();
    }
    }

    ReplyDelete
  3. You can avoid the error too many future call 11 by putting else block :
    if(System.isFuture()) {
    return;
    }
    else{
    asyncApex.processAccounts(Trigger.newMap.keySet());

    }
    }

    ReplyDelete