2014-09-12 3 views
1

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

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

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

Благодаря

EDIT: Вот мой код:

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 на замес

Благодаря

ответ

0

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

+0

Ну, в таком случае пакетное задание, вызванное триггером, должно быть вызвано 15 раз (200 * 15 для 3000 записей), и я удалю 5 ограничение по пакетному заданию. Но этого не происходит, для 3000 записей работает только 3 пакетных задания, так как размер партии составляет 1000 в загрузчике данных. Я просто хочу, чтобы эти 1000 записей были переданы как параметр в пакетный класс, но я получаю первые 200. Где остальные 800? Следующее задание получает записи от Test1000 до Test1200. –

+0

напишите свой код. – superfell

+0

hi @superfell Добавлено мой код –

1

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

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