Salesforce after insert/after update触发器执行顺序控制问题
Salesforce Case触发器插入时触发afterUpdate问题修复
根因说明
- 你的触发器分支判断逻辑本身没有错误,问题出在
DuplicateTicketHandler的afterInsert方法中:你对匹配到的重复子Case执行了update updatedChuld更新操作,该DML会再次触发Case对象的触发器,此时触发的是更新事件,因此会连带执行afterUpdate逻辑。 - 现有代码额外存在批量逻辑漏洞:
afterUpdate方法中遍历newAcc时仅保存了最后一条Case的新旧值,批量操作时逻辑会完全不符合预期。
修复方案
1. 新增静态递归控制变量,拦截重复触发
在Handler类中添加静态布尔变量作为开关,避免同一次事务中触发器被重复调用执行逻辑。
2. 修复批量逻辑适配问题
修改afterUpdate逻辑,适配多条记录批量操作的场景。
3. 优化SOQL查询,减少governor limit消耗
合并重复的SOQL查询,降低资源占用。
修复后完整代码
DuplicateTicketHandler类
public class DuplicateTicketHandler { // 事务级递归控制静态变量,默认false允许执行逻辑 public static Boolean isTriggerExecuting = false; public void afterinsert(List<Case> newcase){ // 递归拦截 if(isTriggerExecuting) return; isTriggerExecuting = true; List<String> newNaturofIssue = new List<String>(); List<String> newFacility = new List<String>(); List<Case> updatedChuld = new List<Case>(); Case parentCase; for(Case cs : newcase){ newNaturofIssue.add(cs.Nature_of_issue_Formula__c); newFacility.add(cs.Facility_Formula__c); } // 一次查询拿到所有匹配记录,按创建时间排序 List<Case> matchCases = [Select Id,Status,createdDate,Nature_of_issue_Formula__c,Facility_Formula__c from Case where status <> 'closed' and Nature_of_issue_Formula__c IN :newNaturofIssue and Facility_Formula__c IN :newFacility order by createdDate asc]; if(matchCases.size() > 1){ parentCase = matchCases[0]; // 从第二条开始都是子Case for(Integer i=1; i<matchCases.size(); i++){ matchCases[i].ParentId = parentCase.Id; updatedChuld.add(matchCases[i]); } } System.debug('childupdated===>'+updatedChuld); if(updatedChuld.size() > 0){ update updatedChuld; } // 重置开关,避免同一次会话后续操作被拦截 isTriggerExecuting = false; } public void afterUpdate(List<Case> OldAcc , List<Case> newAcc, Map<Id, Case> newCase, Map<Id, Case> oldCase){ // 递归拦截 if(isTriggerExecuting) return; isTriggerExecuting = true; List<String> newNaturofIssue = new List<String>(); List<String> newFacility = new List<String>(); List<Case> childtoupdate= new List<Case>(); for(Case cs : OldAcc){ newNaturofIssue.add(cs.Nature_of_issue_Formula__c); newFacility.add(cs.Facility_Formula__c); } List<Case> matchCases = [Select Id,Status,createdDate,Nature_of_issue_Formula__c,Facility_Formula__c from Case where status <> 'Closed' and Nature_of_issue_Formula__c IN :newNaturofIssue and Facility_Formula__c IN :newFacility order by createdDate asc]; if(matchCases.size() <= 1){ isTriggerExecuting = false; return; } Case parentCase = matchCases[0]; List<Case> childCases = matchCases.subList(1, matchCases.size()); Case oldParent = oldCase.get(parentCase.Id); Case newParent = newCase.get(parentCase.Id); // 父Case属性变化时同步子Case if(oldParent != null && newParent != null){ Boolean needSync = (String.valueOf(oldParent.OwnerId).startsWith('00G') && oldParent.Status == newParent.Status) || (oldParent.Status != newParent.Status); if(needSync){ for(Case child : childCases){ child.OwnerId = newParent.OwnerId; child.Status = newParent.Status; childtoupdate.add(child); } } } if (childtoupdate.size()>0) { update childtoupdate; } // 重置开关 isTriggerExecuting = false; } }
DuplicateTicketsTriggerV1触发器
触发器本身的分支判断逻辑无需修改,保持原有代码即可:
trigger DuplicateTicketsTriggerV1 on Case (after insert,after Update) { DuplicateTicketHandler dth = new DuplicateTicketHandler(); if(Trigger.isInsert && Trigger.isAfter){ dth.afterinsert(Trigger.New); } else if(Trigger.isAfter && Trigger.isUpdate){ dth.afterUpdate(Trigger.Old, Trigger.New, trigger.newMap, trigger.oldMap); } }
内容的提问来源于stack exchange,提问作者ambush kumar singh
相关产品推荐
相关产品推荐

