У меня есть процесс, созданный с помощью Process Builder. Он срабатывает при обновлении/создании контакта.

При определенных условиях этот процесс запускает Flow. Поток принимает два параметра — ContactId и AccountId.

Если я делаю массовое обновление/вставку контактов, и поток запускается через процесс, поток автоматически группируется без учета того факта, что сам поток принимает одно значение каждого идентификатора. Итак, если я загружу 100 контактов, поток будет запрашивать информацию о связанных учетных записях в одном запросе.

Есть ли способ реализовать такое же поведение при запуске Flow из апекса?

Я пробовал что-то вроде кода ниже, но он просто запускал поток 4 раза и даже помещал его в одну и ту же транзакцию вершины.

Map<String, String> allParams = new Map<String, String>();
allParams.put('003XXXXXXXXXXX1', '001XXXXXXXXXXX1');
allParams.put('003XXXXXXXXXXX2', '001XXXXXXXXXXX2');
allParams.put('003XXXXXXXXXXX3', '001XXXXXXXXXXX3');
allParams.put('003XXXXXXXXXXX4', '001XXXXXXXXXXX4');

for(String contactId : allParams.keySet()){
    Map<String, Object> params = new Map<String, Object>();
    params.put('ContactId', contactId);
    params.put('AccountId', allParams.get(contactId));
    Flow.Interview myFlow = Flow.Interview.createInterview('GreatestFlowOfAllTimes', params));
    myFlow.start();
}

Я также пытался передать список параметров вместо отдельных значений, например:

Map<String, Object> params = new Map<String, Object>();
            params.put('ContactId', new List<Id>{003XXXXXXXXXXX1, 003XXXXXXXXXXX2, 003XXXXXXXXXXX3, 003XXXXXXXXXXX4});
            params.put('AccountId', new List<Id>{001XXXXXXXXXXX1, 001XXXXXXXXXXX2, 001XXXXXXXXXXX3, 001XXXXXXXXXXX4});
            Flow.Interview myFlow = Flow.Interview.createInterview('GreatestFlowOfAllTimes', params));
            myFlow.start();

И это тоже не работает.

Документация не содержит информации о массовом объединении. вообще.

Может быть, я что-то упускаю. Пожалуйста, порекомендуйте.

7
Andrey Shkolnikov 29 Июл 2019 в 11:32

2 ответа

Вызов start() для объекта потокового интервью в цикле НЕ является массовым, даже если все объекты потокового интервью относятся к одному и тому же потоку.

Это должно быть потому, что метод start() выполняется синхронно

Итак, когда это имеет значение?

  • Если поток, который вы вызываете,
    • Получить запись (SOQL — с учетом 101 за транзакцию (синхронизацию)) или
    • любой из элементов DML — создание/обновление/удаление — с учетом общих ограничений DML для транзакций

Есть причина, по которой документация Apex Flow.Interview ориентирована на случаи использования контроллера apex — когда вы, вероятно, будете работать с одной записью и вызывать start() только один раз.

Теперь, вы можете обойти это? Да, но за плату

Если вы проектируете вызываемый поток таким образом, чтобы он принимал в качестве входных данных набор объектов и возвращал набор результатов, то вам потребуется код Apex только для маршалинга всех входных данных в один набор, вызова start() один раз, а затем демаршалирования. результаты после того, как Поток вернулся.

Вы можете увидеть простой пример этого в Record Updater из Поток звонков AndyInTheCloud из записи блога Apex

Цена? В зависимости от вашего варианта использования, если поток выполняет какое-либо взаимодействие с базой данных, поскольку одно Flow Interview будет перебирать набор входных данных, он должен создавать наборы переменных в циклах, чтобы для каждого Flow Interview выполнялся один SOQL или DML. С таким же успехом вы можете закодировать логику в Apex, а не пытаться воспроизвести лаконичность логики управления Apex в элементах Flow Loop, Assignment и Decision.

Другие ссылки

2
cropredy 11 Июн 2021 в 22:16

Вот некоторая документация по увеличению потока.

https://help.salesforce.com/articleView?id=flow_concepts_bulkification.htm&type=5

Насколько я понимаю, Salesforce будет «разумно» увеличивать объем запроса, чтобы оставаться в рамках ограничений, но каждое собеседование все равно должно выполняться независимо после запроса.

Тем не менее, он всегда казался мне немного мягким, и я не хочу использовать pb/flow в случаях, когда потребуется набухание.

1
gorav 29 Июл 2019 в 13:21
В этой статье объясняется, как управлять самим потоком. Но я ищу способ воспроизвести поведение потока при запуске из апекса. Кажется крайне странным, что мы не можем запустить поток для апекса так же, как он запускается из PB, поэтому я предполагаю, что просто что-то упустил.
 – 
Andrey Shkolnikov
29 Июл 2019 в 13:39
1
Теперь я вижу, согласен, что это должно быть осуществимо. Дикое предположение, но что, если вы сначала добавите все интервью в список потоковых интервью, а затем выполните итерацию по списку, чтобы вызвать метод запуска. Сомневаюсь, что это что-то изменит. Хороший вопрос, надеюсь, кто-то может уточнить.
 – 
gorav
29 Июл 2019 в 15:30
Я тоже пробовал. Это работает так же
 – 
Andrey Shkolnikov
29 Июл 2019 в 16:01
Любое обновление по этому поводу?
 – 
Matthew Metros
19 Апр 2020 в 01:19
3
У меня была такая же мысль, чтобы перебрать список потоков, которые можно запустить последовательно, чтобы увидеть, достаточно ли умна система, чтобы их увеличить... Это не так. Нам нужен такой метод, как Flow.Interview.start(listOfInterviews);
 – 
NSjonas
13 Май 2020 в 22:13