Преодоление триггеров-регуляторов Salesforce - PullRequest
0 голосов
/ 09 апреля 2010

Я пытаюсь написать триггер «после обновления», который выполняет пакетное обновление всех дочерних записей только что обновленной записи. Это должно быть в состоянии обрабатывать 15 000+ дочерних записей одновременно. К сожалению, предел составляет 100, что намного ниже моих потребностей, что даже близко не приемлемо. Я не пробовал разбивать записи на партии по 100 штук, так как это по-прежнему ограничивает 10 тыс. Обновлений на выполнение триггера. (Может быть, я мог бы просто сработать последовательно?)

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

Редактировать: я пытался вызвать следующую функцию @future в моем триггере, но она никогда не обновляет дочерние записи:

global class ParentChildBulkUpdater
{
    @future 
    public static void UpdateChildDistributors(String parentId) {
        Account[] children = [SELECT Id FROM Account WHERE ParentId = :parentId];

        for(Account child : children)
            child.Site = 'Bulk Updater Fired';
        update children;

    }
}

Ответы [ 6 ]

4 голосов
/ 05 мая 2011

Лучший (и самый простой) путь для решения этой проблемы - использовать Пакетный апекс , вы можете создать пакетный класс и запустить его из триггера. Как и @future, он работает в отдельном потоке, но может обрабатывать до 50 000 000 записей!

Перед использованием database.executeBatch вам нужно будет передать некоторую информацию в ваш пакетный класс, чтобы у него был список родительских идентификаторов для работы, или вы могли бы просто получить все учетные записи;)

Я только что заметил, сколько лет этому вопросу, но, надеюсь, этот ответ поможет другим.

2 голосов
/ 09 апреля 2010

Хуже всего то, что вы даже не сможете получить эти 15 тыс. Записей во-первых, потому что в триггере есть ограничение в 1000 строк (это масштабируется до количества строк, которые запускает триггер требуется, но это, вероятно, не помогает)

Полагаю, ваш единственный способ сделать это с тегом @future - читайте об этом в документации. Это дает вам гораздо более высокие ограничения. Несмотря на то, что вы можете вызывать только столько из них в день, вам может понадобиться каким-то образом отслеживать, какие родительские объекты обновляют свои дочерние объекты, а затем обрабатывать их в автономном режиме.

Последний вариант может заключаться в использовании API через какой-либо внешний инструмент. Но вам все равно нужно убедиться, что все в вашем коде объединено.

Сначала я думал, что эти лимиты драконовские, но на самом деле вы можете сделать из них очень много, если вы правильно пакетируете вещи, мы регулярно обновляем 1000 строк из триггеров. И с архитектурной точки зрения, гораздо более того, и вы все равно говорите о пакетной обработке, которая обычно не активируется триггером. Одно можно сказать наверняка - они заставляют вас прыгать через обручи, чтобы сделать это.

1 голос
/ 11 апреля 2010

@ future не работает (не обновляет записи вообще)? Weird. Вы пробовали использовать свою функцию в автоматическом тестировании? Он должен работать, и аннотация должна игнорироваться (во время теста он будет выполняться мгновенно, методы тестирования имеют более высокие пределы). Я предлагаю вам исследовать это немного подробнее, это кажется лучшим решением для того, чего вы хотите достичь.

Кроме того - может быть, попытаться вызвать его из вашего класса, а не триггер?

Триггеры с последовательным соединением не будут работать, я пробовал это в прошлом.

Ваш последний вариант может быть пакетным Apex (начиная с выпуска Winter'10, поэтому он должен быть у всех организаций). Он предназначен для массовых обновлений / проверок заданий, обычно выполняемых в одночасье в обычных базах данных (это можно запланировать). См. http://www.salesforce.com/community/winter10/custom-cloud/program-cloud-logic/batch-code.jsp и примечания к выпуску в формате PDF.

1 голос
/ 09 апреля 2010

Я думаю, что Кодек прав, и путь по API / внешнему инструменту - хороший путь. Ограничения регулятора все еще применяются, но они гораздо менее строгие с вызовами API. Salesforce недавно обновила свой инструмент DataLoader, так что это может быть чем-то, на что можно обратить внимание.

Еще одна вещь, которую вы можете попробовать, - это использовать правило рабочего процесса с исходящим сообщением для вызова веб-службы на вашем конце. Просто отправьте родительский объект и позвольте процессу на вашем конце обрабатывать обновления дочерней записи через API. Одна вещь, о которой следует помнить с исходящими сообщениями, лучше всего как-то поставить в очередь процесс и сразу же ответить на Salesforce. В противном случае Salesforce повторно отправит сообщение.

0 голосов
/ 13 февраля 2011

Возможно, изменение вашей модели данных - лучший вариант здесь. Подумайте о создании формулы для дочернего объекта, где вы получаете доступ к данным из родительского объекта. Это было бы гораздо эффективнее, вероятно.

0 голосов
/ 10 апреля 2010

Я полагаю, что в версии 18 API предел 1000 был удален. (так говорится в документации, но в некоторых случаях я все еще достигаю предела)

Так что вы можете использовать пакетный апекс. С одним оператором обновления APEX

Что-то вроде:

Список детей = новый список {};

для (childObect__c c: [SELECT ....]) {

c.foo__c = 'bar';

children.add (с);

} обновление (дети) ;;

Не забудьте, что вы увеличите тигра, см. Также http://sfdc.arrowpointe.com/2008/09/13/bulkifying-a-trigger-an-example/

...