我们已经为联系人记录编写了重复数据删除逻辑,我们从触发器调用批处理作业(是的,这听起来很奇怪,但似乎唯一可行的是因为我们对每个帐户都有可变标准)。为了克服批量计划限制5,我们使用启用了批量API的数据加载器,并将natch大小设置为1000,这样我们就可以成功上传5000条记录而无需达到5批次作业限制。当我测试3000万条联系人记录时,让我们说它们从Test0001命名为Test3000,我观察到一种奇怪的行为。
对于3000条记录,3个批处理作业开始运行(批处理大小为1000)。我将参数中新插入的记录传递给有状态批次类。我期望的是,将为3个批处理作业中的每一个传递1000条记录,并将它们与重复的现有记录(我在批处理的启动方法中查询)进行比较,但我只将Test0001提供给Test0200,即批次为1000条记录通过数据加载器API插入只有FIRST 200记录在参数中传递给批次类,而其余800则不是。如果我通过启用Bulk API的数据加载器使用批量大小1000插入,那么这意味着只有前200个记录是进程。
您是否有人遇到此问题或有任何想法分享如何处理它?我也可以分享代码,但我认为问题更具概念性。非常感谢任何帮助。
由于
编辑:这是我的代码:
This is the call from after insert triiger -->
ContactTriggerHandler trgHandler = new ContactTriggerHandler();
trgHandler.deDupAndCreateOfficebyBatch(accountIdContactMap);
//accountIdContactMap is the map which contains List of new contacts w.r.t thier account.
This is the call from handler class -->
public void deDupAndCreateOfficebyBatch (Map<String,List<Contact>> accountIdContactMap){
ContactDeDuplicationBatch batchObj = new ContactDeDuplicationBatch(accountIdContactMap);
String jobId = Database.executeBatch(batchObj,100);
}
This is the batch -->
global class ContactDeDuplicationBatch implements Database.Batchable<sObject>, Database.Stateful{
//set of duplicate contacts to delete
global Set<Contact> duplicateContactSet;
//Map of list of new contacts with account id as key
global Map<String,List<Contact>> newAccIdContactMap;
/*Constructor*/
public ContactDeDuplicationBatch(Map<String,List<Contact>> accountIdContactMap){
System.Debug('## accountIdContactMap size = '+ accountIdContactMap.keySet().size());
newAccIdContactMap = accountIdContactMap;
duplicateContactSet = new Set<Contact>();
}
/*Start Method */
global Database.QueryLocator start(Database.BatchableContext BC){
System.Debug('## newAccIdContactMap size = '+ newAccIdContactMap.keySet().size());
if(newAccIdContactMap.keySet().size() > 0 && newAccIdContactMap.values().size() > 0){
//Fields to be fetched by query
String fieldsToBeFetched = 'Id, AccountId ';
//Add account Id's for contacts which are to be matched
String accountIds = '(';
for(String id : newAccIdContactMap.keySet()){
if(accountIds == '('){
accountIds += '\''+id+'\'';
}else{
accountIds += ', \''+id+'\'';
}
}
accountIds += ')';
String query = 'SELECT '+fieldsToBeFetched+' FROM Contact WHERE Target_Type__c <> \'Office\' AND AccountId IN '+accountIds;
return Database.getQueryLocator(query);
} else {
return null;
}
}
/*Execute Method */
global void execute(Database.BatchableContext BC, List<sObject> scope){
System.Debug('## scope.zixe '+scope.size());
System.Debug('## newAccIdContactMap.zixe '+newAccIdContactMap.size());
//In My execute method I get only 200 records in newAccIdContactMap per batch
}
/*Finish Method */
global void finish(Database.BatchableContext BC){
//Some logic using the two global variables
}
}
在我的执行方法中,我每批在newAccIdContactMap中只获得200条记录
由于
答案 0 :(得分:1)
Batch Apex限制为5适用于已计划和正在运行的流程。
从触发器执行批处理顶点时应特别小心。你几乎总是会达到极限。最好先加载数据,然后再运行批处理(不是从触发器开始)一次处理所有内容。
答案 1 :(得分:0)
触发器最多以200个记录的批量处理,因此对于1000个记录的批量加载,您的触发器将被调用5次,每组有200个记录。