Получение тех же 200 записей только в каждом триггере при использовании BULK API через Data Loader

Мы написали логику дедупликации для записей контактов, в которой мы вызываем пакетное задание из триггера (да, это звучит странно, но единственное, что, похоже, работает, поскольку у нас есть переменные критерии для каждой учетной записи). Чтобы преодолеть ограничение в 5 пакетных заданий, мы используем загрузчик данных с включенным массовым API и размером natch, равным 1000, чтобы мы могли успешно загрузить 5000 записей, не превышая ограничение в 5 пакетных заданий. Когда я тестирую 3000 тысяч записей контактов, скажем, они имеют имена от Test0001 до Test3000, я наблюдаю странное поведение.

Для 3000 записей запускаются 3 пакетных задания (размер пакета равен 1000). Я передаю вновь вставленные записи в параметрах классу пакетной обработки с отслеживанием состояния. Я ожидаю, что для каждого из 3 пакетных заданий будет передано 1000 записей, и они будут сравниваться с существующими записями для дубликатов (которые я запрашиваю в методе запуска пакета), но я получаю только Test0001 до Test0200, то есть из пакета из 1000 записей вставлены через API загрузчика данных, только ПЕРВЫЕ 200 записей передаются в параметре классу пакета, а остальные 800 - нет. Это что-то странное, поскольку это означает, что только первые 200 записей являются процессами, если я вставляю с использованием размера пакета 1000 через загрузчик данных с включенным Bulk API.

Кто-нибудь из вас сталкивался с этой проблемой или у вас есть идеи, которыми можно с ней справиться? Я тоже могу поделиться кодом, но я думаю, что вопрос более концептуальный. Любая помощь горячо приветствуется.

Спасибо

РЕДАКТИРОВАТЬ: вот мой код:

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
}

}

В методе My execute я получаю только 200 записей в newAccIdContactMap на пакет

Спасибо


person Shahid Ali    schedule 12.09.2014    source источник


Ответы (2)


Ограничение Batch Apex, равное 5, применяется как к запланированным, так и к запущенным процессам.

Вы должны быть очень осторожны при выполнении пакетного апекса из триггера. Вы почти всегда достигаете пределов. Было бы лучше сначала загрузить ваши данные, а затем запустить пакет вторым (не из триггера), чтобы обработать все сразу.

person ScottW    schedule 14.09.2014

Триггеры обрабатываются партиями не более 200 записей, поэтому при пакетной загрузке 1000 записей ваш триггер будет вызываться 5 раз с 5 различными наборами по 200 записей.

person superfell    schedule 12.09.2014
comment
Что ж, в этом случае пакетное задание, вызываемое из триггера, должно вызываться 15 раз (200 * 15 для 3000 записей), и я достигну ограничения в 5 пакетных заданий. Но этого не происходит, для 3000 записей выполняется только 3 пакетных задания, поскольку размер пакета составляет 1000 в загрузчике данных. Я просто хочу, чтобы эти 1000 записей были переданы как параметр пакетному классу, но я получаю первые 200. Куда идут остальные 800? Следующее задание получает записи от Test1000 до Test1200. - person Shahid Ali; 12.09.2014