Salesforce中避免重复执行Trigger的思路

题外话,换了效力的公司之后,对自己的冲击还是挺大的。所以一直没有精力继续写。不过,还是一鼓作气吧。

第一种思路:在trigger中声明一个Static变量,默认为false,如果执行了业务代码,在最后将此变量值执为True,然后在一个事务中,下次再进来的时候,由于此变量为true,跳过。

但是由于static的机制并不是很稳定,有可能造成意想不到的问题。而且,在早些年版本的时候,一个批次200条数据,salesforce会分两次执行。这样后100条就会被无情的跳过。

第二种思路:在目标object上新建一个隐藏的布尔字段,默认为false,第一次执行的时候将此字段的值更新成true,然后在事务结束的时候使用future方法重新更新为false。

超大量导入数据的时候应该会死。。。

第三种思路:新建一个static class,class里面包含一个set,然后每次事务开始时将自己放入此set,事务结束时remove掉。

仍然有static诡异行为或者直接失效的风险。

所以,在表设计和业务结构设计的时候还是要尽量发生重复触发的情景。让Trigger只关注与自己要做的事情就好。

之后会给出每种思路的验证结果。

// Update 1 by 2017/03/04

应群众要求,解释一下思路一。
思路一的核心就在于static修饰符。官方文档
熟悉高级编程语言的同学一定对static不陌生,比如在java中static经常与public final static连用。
Salesforce同样提供了static概念,不过于java中的static有些不同。
1. static的生存范围仅限一个transaction。所以幻想着初始化一次到处使用的,洗洗睡吧。
2. 虽然不能做到亘古不变,但是在一个transaction内穿梭于多个instance之间还是可以的。
同样,可以在class中的static代码块中进行复杂的初始化,也是能避免重复执行。

所以作为思路一的解决方案。就如同官方文档提供的例子一样。
首先找一个class声明一个flag。

public class P { 
   public static boolean firstRun = true; 
}

然后在业务代码里使用它。

trigger T1 on Account (before delete, after delete, after undelete) { 
       if(Trigger.isBefore){
          if(Trigger.isDelete){
             if(p.firstRun){
                 Trigger.old[0].addError('Before Account Delete Error');
                  p.firstRun=false;
              } 
           }
        }
}

《Salesforce中避免重复执行Trigger的思路》有一个想法

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据