3

我在删除触发器之前运行 Apex 作业,并注意到通过 Salesforce 界面删除单个营销活动大约需要 34 秒,并且当营销活动被删除时,Apex 作业已完成运行。当我使用 VisualForce 页面在相同数量的记录 (15,000) 上运行相同的 Apex 作业时,Apex 作业会排队并在 VisualForce 页面完成后运行。

在此屏幕截图中,第一个作业使用 VisualForce 排队,第二个和第三个作业使用触发器排队:

顶点工作

如您所见,虽然相同数量的记录 (15,000) 在使用触发器排队时由相同的 Apex 作业处理,但没有创建批次,提交和完成日期完全不同。

Apex 作业在触发器中排队:

trigger DeleteChilds on Campaign (before delete) {
public static final Integer MAX_DELETED = 500;
Set<ID> ids = new Set<Id>();
List<Parent__c> objs = new List<Parent__c>();   

for(Campaign c : Trigger.old)
    ids.add(c.Id);

objs = [SELECT Id FROM Parent__c WHERE Campaign__c IN :ids];

ids = new Set<Id>();

for(Parent__c s : objs)
    ids.add(s.Id);

Integer childCount = [SELECT count() FROM Childs__c WHERE Parent__c IN :ids];

if(childCount < MAX_DELETED){
    List<Childs__c> childs = [SELECT Id FROM Childs__c WHERE Parent__c IN :ids];

    delete childs;  
} else {                 
    String deleteQuery = 'SELECT Id FROM Childs__c WHERE ';

    for(ID id : ids){
        deleteQuery += String.format(' Parent__c = \'\'{0}\'\' OR', new String[] {id});
    }   

    if(deleteQuery.endsWith('OR')){
        deleteQuery = deleteQuery.substring(0, deleteQuery.length() - 2);
    }               

    BatchDeleteChilds batch = new BatchDeleteChilds();
    batch.deleteQuery = deleteQuery;

    ID batchId = Database.executeBatch(batch);      
}

delete objs;
}

这是 Apex 作业:

global class BatchDeleteChilds implements Database.Batchable<sObject> {
public String deleteQuery;

global Database.QueryLocator start(Database.BatchableContext context){
    return Database.getQueryLocator(deleteQuery);
}

global void execute(Database.BatchableContext context, List<sObject> records){
    delete records;
    DataBase.emptyRecycleBin(records);
}   

global void finish(Database.BatchableContext context){

}   
}

有没有其他人经历过这样的事情?

谢谢,

4

1 回答 1

2

您正在查看一个您可能永远不会赢的比赛条件。已删除的父对象将在批处理作业执行时提交,这将使数据库中从子对象到父对象的查找无效。因此,您传递到批处理中的查询将有零记录。

  • 预删除子项:(name = 'example',parent__c = '123')
  • 删除后(批量前)子项:(名称 = 'example',parent__c = null)

我不知道激发这种方法的设计决策,但还有其他选项可用于批量删除子记录。最简单的方法是让孩子与父母的关系成为主要细节。使用这种类型的关系会自动删除子记录。

其次,您可以使用 visualforce 页面覆盖父对象的删除按钮。然后控制器将计算孩子的数量并决定是否启动批处理以删除它们。然后让批处理等待删除父对象,直到它的完成方法。

于 2012-07-04T00:37:15.223 回答