Кейс: deadlock из-за асинхронных шагов BPMN

Ситуация

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

На диаграмме шаги выглядели последовательными, но async continuation создавали отдельные задания движка и меняли транзакционные границы.

Диагностика

Я сравнил async-настройки основного и вызываемого процессов и проверил, где движок разрывает последовательное выполнение на отдельные jobs. Рабочая гипотеза состояла в том, что эти границы позволяли зависимым шагам перекрываться. Проверкой стало изменение обеих моделей и повтор сценария.

Мой вклад

Я удалил асинхронные границы на конфликтующих шагах и сделал критический путь последовательным. Изменение охватило основной и вызываемый процессы.

Результат

В проверенном сценарии после синхронизации шагов взаимная блокировка перестала воспроизводиться. Это результат конкретного изменения, а не универсальная защита от любого database deadlock.

Технический вывод

Асинхронный шаг BPMN — не просто способ «не ждать». Это новая единица планирования, возможная новая транзакция и новый конкурент за данные.

Перед добавлением async continuation я теперь проверяю:

  • какие данные читаются и записываются до и после границы;
  • может ли операция повториться;
  • нужен ли фиксированный порядок обновлений;
  • что произойдёт при retry job;
  • не скрыта ли в подпроцессе ещё одна граница.

Связанные заметки