当通过Data Loader使用BULK API时,在每个触发器中获得相同的200个记录

时间:2014-09-12 19:04:29

标签: salesforce apex-code visualforce apex apex-data-loader

我们已经为联系人记录编写了重复数据删除逻辑,我们从触发器调用批处理作业(是的,这听起来很奇怪,但似乎唯一可行的是因为我们对每个帐户都有可变标准)。为了克服批量计划限制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条记录

由于

2 个答案:

答案 0 :(得分:1)

Batch Apex限制为5适用于已计划和正在运行的流程。

从触发器执行批处理顶点时应特别小心。你几乎总是会达到极限。最好先加载数据,然后再运行批处理(不是从触发器开始)一次处理所有内容。

答案 1 :(得分:0)

触发器最多以200个记录的批量处理,因此对于1000个记录的批量加载,您的触发器将被调用5次,每组有200个记录。