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

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

Для 3000 записей запускаются 3 пакетных задания (размер пакета равен 1000). Я передаю вновь вставленные записи в параметрах в пакетный класс с сохранением состояния. Я ожидаю, что 1000 записей будут переданы для каждого из 3 пакетных заданий, и они будут сравниваться с существующими записями для дубликатов (которые я запрашиваю в методе запуска пакета), но я получаю только 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
}

}

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

Спасибо

2 ответа

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

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

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

Другие вопросы по тегам