Кейс: deadlock из-за асинхронных шагов BPMN
Ситуация
При выгрузке нескольких элементов процесс создавал связанные объекты и записывал полученные идентификаторы обратно. В этом сценарии возникала взаимная блокировка.
На диаграмме шаги выглядели последовательными, но async continuation создавали отдельные задания движка и меняли транзакционные границы.
Диагностика
Я сравнил async-настройки основного и вызываемого процессов и проверил, где движок разрывает последовательное выполнение на отдельные jobs. Рабочая гипотеза состояла в том, что эти границы позволяли зависимым шагам перекрываться. Проверкой стало изменение обеих моделей и повтор сценария.
Мой вклад
Я удалил асинхронные границы на конфликтующих шагах и сделал критический путь последовательным. Изменение охватило основной и вызываемый процессы.
Результат
В проверенном сценарии после синхронизации шагов взаимная блокировка перестала воспроизводиться. Это результат конкретного изменения, а не универсальная защита от любого database deadlock.
Технический вывод
Асинхронный шаг BPMN — не просто способ «не ждать». Это новая единица планирования, возможная новая транзакция и новый конкурент за данные.
Перед добавлением async continuation я теперь проверяю:
- какие данные читаются и записываются до и после границы;
- может ли операция повториться;
- нужен ли фиксированный порядок обновлений;
- что произойдёт при retry job;
- не скрыта ли в подпроцессе ещё одна граница.