DDDesigner

Длительные бизнес-процессы

Сага в DDD: координация между агрегатами

Сага координирует бизнес-процесс, который охватывает несколько агрегатов или ограниченных контекстов и не помещается в одну транзакцию. Она хранит прогресс, отправляет команды, ждёт события и обрабатывает сбои. Сага — это модель бизнес-процесса, а не просто технический обработчик очереди. В DDDesigner каждая сага открывается на отдельном холсте: клик в дереве проекта показывает только её шаги и компенсации.

Когда использовать сагу

Сага нужна, когда процесс состоит из нескольких надёжных шагов, пересекает границы согласованности или ждёт внешнего результата. Простая реакция без состояния процесса обычно является политикой.

  • Несколько команд выполняются последовательно
  • Процесс ждёт асинхронных событий
  • Важны timeout и retry
  • Выполненные шаги требуют компенсации

Оркестрация и хореография

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

Компенсация — бизнес-действие

Компенсация не является rollback базы. RefundPayment или ReleaseStock — новая бизнес-операция со своими правилами, сбоями и аудитом.

Сага, политика или простой обработчик события?

Политика обычно является реакцией без состояния: после PaymentReceived отправить письмо. Сага нужна, когда системе нужно помнить, на каком шаге находится процесс, ждать позднее событие, контролировать тайм-аут, повторять шаг или выбирать следующее действие по нескольким результатам.

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

Состояние, корреляция и идемпотентность

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

Сообщения могут доставляться повторно или не по порядку. Поэтому обработчики саги должны быть идемпотентными: повторное подтверждение не должно списывать деньги дважды, а старое событие не должно возвращать завершённый процесс назад. Для корреляции используйте стабильные бизнес-идентификаторы, а не ссылку на объект в памяти.

Оркестрация и хореография на практике

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

Выбирайте подход по сложности и ответственности процесса, а не по лозунгу. Если бизнесу нужно одно место, где видны сроки, компенсации и критерии завершения, оркестрация обычно понятнее.

Сбои, повторы и компенсации

Повтор подходит для временной технической ошибки, например кратковременного сетевого сбоя. Компенсация — новое бизнес-действие, которое отменяет или уравновешивает уже принятый факт: RefundPayment или ReleaseReservedStock. У него есть собственные права, инварианты, ошибки и аудит.

Компенсировать можно не всё. Некоторые действия необратимы, а некоторые требуют ручной проверки. Такие состояния нужно моделировать явно, а не прятать за общим словом «откат». Сага может создать событие о провале процесса, сохранив факты, которые уже произошли.

Чек-лист проверки саги

Сага готова к реализации, когда явно описаны стартовое событие, переходы состояния, команды, ожидаемые события, тайм-ауты и пути ошибок.

  • Какой бизнес-процесс принадлежит саге?
  • Что запускает и завершает его?
  • Как коррелируются экземпляры?
  • Какие шаги можно повторять?
  • Какие ошибки требуют компенсации или человека?
  • Как обрабатываются дубли и поздние сообщения?
  • Видит ли оператор зависший экземпляр?

DDDesigner

Пример: выполнение заказа между контекстами

После OrderPlaced Сага выполнения заказа просит Inventory зарезервировать товар, а Payments — списать деньги. Она хранит идентификаторы заказа и процесса, ждёт оба результата и корректно обрабатывает повторные сообщения. Если оплата не прошла после резервирования, сага отправляет ReleaseStock и фиксирует компенсацию. Если провайдер недоступен дольше установленного срока, процесс переходит в состояние ручной проверки, а не делает вид, что транзакция откатилась. После успеха Inventory, Payments и Shipping сага отправляет ScheduleDelivery и публикует FulfillmentCompleted.

Начать бесплатно