21

So I have been wanting some clear cut answers on this for a while and most of the documentation that I can find is fairly vague.

Mike Leach has an excellent post explaining the best practices in creating triggers. I follow this construct and have 1 and only 1 trigger on each object, and have a handler for each object where I can call different methods to execute the logic for the triggers.

http://www.embracingthecloud.com/2010/07/08/ASimpleTriggerTemplateForSalesforce.aspx

This all works great. My question is how to use trigger.isExecuting() effectively.

Right now in order to avoid recursive calls in my triggers I have created a simple class

public class TriggerContextUtility {

    private static boolean firstRun = true;

    public static boolean isFirstRun() {
        return firstRun;
    }

    public static void setFirstRunFalse(){
        firstRun = false;
    }

} 

That I can call within my trigger to check if the trigger has already been called within the context. I use it like this.

 trigger OpportunityTrigger on Opportunity (after insert, after update, before insert, before update) {

        OpportunityTriggerHelper helper = new OpportunityTriggerHelper();

        if(trigger.isAfter && trigger.isUpdate){

                 if(TriggerContextUtility.isFirstRun()){

                      helper.helperFunction(trigger.new, trigger.old, trigger.newMap, trigger.oldMap);

                      TriggerContextUtility.setFirstRunFalse();
                 }
        }           
    }

This works fine, I just want to make sure I am doing this in the most efficient way. I am just wondering if I can use the trigger.isExecuting context variable to accomplish the same thing. I can't really find this context variable well explained anywhere. The basic definition I find is

"Returns true if the current context for the Apex code is a trigger, not a Visualforce page, a Web service, or an executeanonymous() API call."

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_context_variables.htm

I just dont understand fully what that really means and therefore can't figure out how to leverage it. I see that Mike Leach uses includes the variable in his code, but never actually checks it or has any logic based on it.

Can someone help to explain

  1. What trigger.isExecuting is actually telling us
  2. How to best leverage it
  3. If it can help me get rid of the TriggerContextUtility class that I currently use to avoid recursive trigger calls.

Thanks a lot

2 Answers 2

11

Excellent questions.

"What trigger.isExecuting is actually telling us"

When decoupling the Apex trigger handler class from the actual trigger, the Apex class has no way to know what context it's called in (unit test, web service, visualforce page, trigger). This flag just means the handler was executed by a trigger.

A better name for this flag might be "isCreatedByTrigger".

"How to best leverage it"

At one point I think the intent was to use this flag in unit testing, but Test.isRunningTest() (introduced in v20?) is probably a better solution today.

"If it can help me get rid of the TriggerContextUtility class that I currently use to avoid recursive trigger calls."

All solutions to this problem require some form of static boolean state management, so your code is correct. The isExecuting flag is not applicable to this class of problem.

In fact, the next iteration of my trigger template will probably need to incorporate a static variable to address the recursion problem. Thanks for pointing this out!

-Mike Leach

5
  • Thank you mike, this is very helpful. So really, isExecuting isn't all that necessary? I just wanted to make sure I wasn't missing out on something. Thank you Commented Sep 6, 2013 at 19:05
  • Correct. Not necessary for managing recursive reentry. Not necessary at all? Perhaps. I'll re-evaluate this template for my DF13 presentation and make updates. Thanks!
    – dlog
    Commented Sep 6, 2013 at 19:22
  • Awesome, Ill make sure I'm at that presentation. Thanks agan Commented Sep 6, 2013 at 21:36
  • Trigger.isExecuting isn't anything like Test.isRunningTest. While I've never specifically had a use for this function myself, it can be useful in utility classes where the logic might be called from a Visualforce page or by a trigger; we want the same basic logic in either case, but maybe we want to perform a DML only if it is not called from a Trigger, or we want to determine if Trigger.new/Trigger.old may be available to us.
    – sfdcfox
    Commented Sep 24, 2013 at 22:02
  • In the blog article referenced above, a trigger handler class is passed the isExecuting context, which can be used in unit testing for conditional logic. When 'true', the handler assumes it's being executed in an actual trigger context. When 'false', the class is being executed by a unit test (or VF page controller context).
    – dlog
    Commented Sep 25, 2013 at 13:39
8

There are couple of design concepts/patterns published to handle the apex triggers and some of them had gotten wide acceptance. Check out Dan Appleman's advanced apex programming or Tony Scott's design pattern. You might want to check out my architecture framework to handle the apex triggers as well. This is the most comprehensive architecture framework to handle the apex triggers in Force.com platform that supports recursive triggers along with SOC and others. While none of these design patterns/frameworks can be universal solution, depending on your requirements, I believe they should be hugely beneficial.

Edit:

To answer your question:

a. 'Trigger.isExecuting' can be used anywhere in the apex code. It returns true, if you call it within the trigger context (not just within the trigger, for e.g. if you have a separate class and if you call the method in this class from your trigger, it will still return true).

b. This is best utilized in your helper code, specifically, if the helper code could be called from different places. For e.g. the same helper method in your helper class could be called from your custom controller or trigger code. So call 'Trigger.isExecuting' will help you to identify if the call is from trigger or a visualforce page.

c. At the simplest level, you need a static variable to control the recursion and this is separate from using 'Trigger.isExecuting'. You can either get rid of TriggerContextUtility class, but you still need to have a static variable somewhere and set/unset it to control the recursion.

Here is an example of how to use the static variable and Trigger.isExecuting. This code handles the after update event on the Account object. Note that this example code may not follow the best practices and supposed to demonstrate the concept.

trigger AccountTrigger on Account (after insert, after update) {
    AccountTriggerHandler.handleAccountEvents(Trigger.isExecuting, Trigger.isBefore, Trigger.isAfter, Trigger, isInsert, Trigger.isUpdate, Trigger.new, Trigger.old);
}

public class AccountTriggerHandler {
    // you need one static variable for each event type. 
    public static Boolean isAfterInsertFlag = false;
    public static Boolean isAfterUpdateFlag = false;

    public static void handleAccountEvents(Boolean isExecuting, Boolean isBefore, Boolean isAfter, Boolean isInsert, Boolean isUpdate, List<Account> listNewAccounts, List<Account> listOldAccounts) {

        if(isAfter && isUpdate) { // handle after update event
            if(isAfterUpdateFlag == false) { // if this is the first call
                isAfterUpdateFlag = true; // set the static variable to indicate that the call is in progress for after update event.
                AccountHelper.updateOwner(isExecuting, listNewAccounts);
            }
        }
    }
}

public class AccountHelper {
    public static void updateOwner(Boolean isTrigger, List<Account> listAccounts) {

        if(isTrigger) { // if the running context originated from trigger invocation
            // do what ever you want to do as part of the trigger invocation
        } else {
            // do what ever you want to do if the call originated from different context, such as from controller.
        }
    }
}
3
  • I updated the answer with example code. Commented Sep 6, 2013 at 19:03
  • Thank you for this. So I guess its just whether or not we want to have an external class or keep it internal. Thank you though. +1 Commented Sep 6, 2013 at 19:06
  • Thank you :) Shouldn't 'public void handleAccountEvents' be static though? Commented Feb 24, 2017 at 15:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .