竞价排名Demo - after insert / after update更新记录(防止递归)
2017-06-23 18:06
399 查看
背景介绍:现有应标对象,供应商和招标项目三个对象,其中应标对象为junction object,连接了供应商和招标项目,现在需要根据应标对象中的竞价金额为同一招标项目的应标记录进行排序,即新建一个应标记录或更新应标记录的竞价金额的时候,需要自动去计算当前应标记录的排名(竞价排名)。
Trigger设计模式:每个对象一个Trigger模式。
TriggerHandler.cls
/**********************************************************************
*Name:所有对象的Trigger逻辑分发抽象类
*Description:具体对象的Trigger Handler重写相应触发事件的处理方法
======================================================
History
-------
VERSION AUTHOR DATE DETAIL
1.0 Wilson Xu 2017-06-23 Created
***********************************************************************/
public abstract class TriggerHandler {
public virtual void beforeInsert(){} //before insert事件处理方法
public virtual void beforeUpdate(){} //before update事件处理方法
public virtual void beforeDelete(){} //before delete事件处理方法
public virtual void afterInsert(){} //after insert事件处理方法
public virtual void afterUpdate(){} //after update事件处理方法
public virtual void afterDelete(){} //after delete事件处理方法
public virtual void afterUndelete(){} //after undelete事件处理方法
public void run(){
if(Trigger.isBefore && Trigger.isInsert) {
this.beforeInsert();
} else if(Trigger.isBefore && Trigger.isUpdate) {
this.beforeUpdate();
} else if(Trigger.isBefore && Trigger.isDelete) {
this.beforeDelete();
} else if(Trigger.isAfter && Trigger.isInsert) {
this.afterInsert();
} else if(Trigger.isAfter && Trigger.isUpdate) {
this.afterUpdate();
} else if(Trigger.isAfter && Trigger.isDelete) {
this.afterDelete();
} else if(Trigger.isAfter && Trigger.isUndelete) {
this.afterUndelete();
}
}
}BidRecordTrigger.trigger
解决方案:目前有两种方案,一种是为触发器增加一个布尔类型的开关来控制死循环;另一种是“用完即走”的理念,即“按需调用方法,档需要去执行某段逻辑时,才去调用相应的方法”,我同事于是说。
补充:在after trigger里面再去更新记录,就会无限循环,造成query 101。
Salesforce官方提供的防止递归策略:
Class Code:
public Class checkRecursive{
private static boolean run = true;
public static boolean runOnce(){
if(run){
run=false;
return true;
}else{
return run;
}
}
}Trigger Code:
Trigger设计模式:每个对象一个Trigger模式。
TriggerHandler.cls
/**********************************************************************
*Name:所有对象的Trigger逻辑分发抽象类
*Description:具体对象的Trigger Handler重写相应触发事件的处理方法
======================================================
History
-------
VERSION AUTHOR DATE DETAIL
1.0 Wilson Xu 2017-06-23 Created
***********************************************************************/
public abstract class TriggerHandler {
public virtual void beforeInsert(){} //before insert事件处理方法
public virtual void beforeUpdate(){} //before update事件处理方法
public virtual void beforeDelete(){} //before delete事件处理方法
public virtual void afterInsert(){} //after insert事件处理方法
public virtual void afterUpdate(){} //after update事件处理方法
public virtual void afterDelete(){} //after delete事件处理方法
public virtual void afterUndelete(){} //after undelete事件处理方法
public void run(){
if(Trigger.isBefore && Trigger.isInsert) {
this.beforeInsert();
} else if(Trigger.isBefore && Trigger.isUpdate) {
this.beforeUpdate();
} else if(Trigger.isBefore && Trigger.isDelete) {
this.beforeDelete();
} else if(Trigger.isAfter && Trigger.isInsert) {
this.afterInsert();
} else if(Trigger.isAfter && Trigger.isUpdate) {
this.afterUpdate();
} else if(Trigger.isAfter && Trigger.isDelete) {
this.afterDelete();
} else if(Trigger.isAfter && Trigger.isUndelete) {
this.afterUndelete();
}
}
}BidRecordTrigger.trigger
/********************************************************************** *Name:应标记录触发器 *Description:可加一些其他条件限制Trigger是否触发,比如加一个控制Trigger逻辑是否触发的Custom Setting,满足条件则运行run(),否则不运行 ====================================================== History ------- VERSION AUTHOR DATE DETAIL 1.0 Wilson Xu 2017-06-23 Created ***********************************************************************/ trigger BidRecordTrigger on Advertiser_Tender_Relationship__c (before insert,before update,before delete,after insert,after update,after delete,after undelete) { SkipTriggerSetting__c setting = SkipTriggerSetting__c.getInstance(); //如果当前用户设置了不触发Trigger,跳过Trigger触发逻辑 if (setting != null && setting.DisableTrigger__c){ return; } new BidRecordTriggerHandler().run(); }BidRecordTriggerHandler.cls
public class BidRecordTriggerHandler extends TriggerHandler { /** before insert事件处理逻辑 **/ public override void beforeInsert() { } /** after insert事件处理逻辑 **/ public override void afterInsert() { } /** before update事件处理逻辑 **/ public override void beforeUpdate() { } /** after update事件处理逻辑 **/ public override void afterUpdate() { /** before delete事件处理逻辑 **/ public override void beforeDelete() { } /** after delete事件处理逻辑 **/ public override void afterDelete() { } /** after undelete事件处理逻辑 **/ public override void aft b6dc erUnDelete() { } }BidRecordTriggerFunction.cls
public class BidRecordTriggerFunction { public static boolean isExecuting = false;// avoid recursion /** 功能说明:根据应标金额排序 参数说明:应标记录集合 返回值:null 作者:Wilson 日期:2017-06-20 **/ public static void sortByBidAmount(List<Advertiser_Tender_Relationship__c> atrs){ if(BidRecordTriggerFunction.isExecuting) { return; } BidRecordTriggerFunction.isExecuting = true; // excute your code logic. such as update Advertiser_Tender_Relationship__c list records. BidRecordTriggerFunction.isExecuting = false; } }遇到过的问题:假如没做递归处理,在after update的Trigger中更新竞价排名字段,会因为递归而报错,最终导致并没有更新竞价排名。
解决方案:目前有两种方案,一种是为触发器增加一个布尔类型的开关来控制死循环;另一种是“用完即走”的理念,即“按需调用方法,档需要去执行某段逻辑时,才去调用相应的方法”,我同事于是说。
补充:在after trigger里面再去更新记录,就会无限循环,造成query 101。
Salesforce官方提供的防止递归策略:
Class Code:
public Class checkRecursive{
private static boolean run = true;
public static boolean runOnce(){
if(run){
run=false;
return true;
}else{
return run;
}
}
}Trigger Code:
trigger updateTrigger on anyObject(after update) { if(checkRecursive.runOnce()) { //write your code here } }参考资源:https://help.salesforce.com/articleView?id=000133752&language=en_US&type=1
相关文章推荐
- 如何用insert或update在同一表中插入或更新多条记录
- 公司培训讲义[Ajax基础二,课件及Demo下载)(内容更新到UpdatePanel)
- 根据数据库自动生成INSERT/UPDATE更新语句
- [SQL Server 2005/2008]递归更新update(使用CTE公用表达式)
- Hibernate 有选择性的更新--控制insert和update语句
- MySQL 当记录不存在时insert,当记录存在时update
- [提问]用textBox绑定数据,为何用Update更新时一定要移动到别的记录?
- PostgreSQL数据库添加更新只用一个函数insertupdate
- [转]MSSQL数据库触发器--更新(update),删除(delete),插入(insert)
- MySQL 当记录不存在时insert,当记录存在时update
- 关于ADO.Net使用TableAdapter时产生:更新要求有效的deletecommand或update,insert,selectcommand的解决办法,以及“违反并发性”处理
- SQL0803N INSERT 语句、UPDATE 语句或由 DELETE 语句导致的外键更新中的一个或多个值无效,因为由 "1" 标识的主键、唯一约束或者唯一索引将表
- 如何在插入记录以前锁住表,不允许别的insert,update,del动作
- 企业级应用开发历险记----更新一条记录不仅是update
- sql使用递归更新树级表记录
- 公司培训讲义[Ajax基础二,课件及Demo下载)(内容更新到UpdatePanel)
- ACCESS的真假:二、检查记录有无再insert 或 update 比 不管有无直接 delete 再 insert 快吗?
- 提高数据更新效率(UPDATE/INSERT)
- Ms Sql 触发器之 ------ 简单更新 Insert 中的记录
- mysql insert if not exists防止插入重复记录的方法