Получение тех же 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 записей.