Когда использовать сагу
Сага нужна, когда процесс состоит из нескольких надёжных шагов, пересекает границы согласованности или ждёт внешнего результата. Простая реакция без состояния процесса обычно является политикой.
- Несколько команд выполняются последовательно
- Процесс ждёт асинхронных событий
- Важны timeout и retry
- Выполненные шаги требуют компенсации
Оркестрация и хореография
Оркеструемая сага явно выбирает следующую команду и хранит состояние. При хореографии реакции распределены между участниками. Оркестрацию легче анализировать в сложных потоках, хореография подходит для простых устойчивых взаимодействий.
Компенсация — бизнес-действие
Компенсация не является rollback базы. RefundPayment или ReleaseStock — новая бизнес-операция со своими правилами, сбоями и аудитом.
Сага, политика или простой обработчик события?
Политика обычно является реакцией без состояния: после PaymentReceived отправить письмо. Сага нужна, когда системе нужно помнить, на каком шаге находится процесс, ждать позднее событие, контролировать тайм-аут, повторять шаг или выбирать следующее действие по нескольким результатам.
Используйте сагу, когда у процесса есть собственный бизнес-жизненный цикл. Если заказчику важно знать, ожидает ли выполнение заказа, заблокировано ли оно, компенсируется или завершено, процессу нужна явная модель и состояние.
Состояние, корреляция и идемпотентность
Сага должна иметь идентификатор корреляции, связывающий команды и события с одним экземпляром бизнес-процесса. В состоянии фиксируются завершённые шаги, ожидаемые действия, сроки и важные решения. Это состояние должно переживать перезапуски, а ожидающие и ошибочные экземпляры должны быть наблюдаемыми.
Сообщения могут доставляться повторно или не по порядку. Поэтому обработчики саги должны быть идемпотентными: повторное подтверждение не должно списывать деньги дважды, а старое событие не должно возвращать завершённый процесс назад. Для корреляции используйте стабильные бизнес-идентификаторы, а не ссылку на объект в памяти.
Оркестрация и хореография на практике
При оркестрации координатор явно отправляет следующую команду и хранит состояние процесса. Такой подход легче объяснять, тестировать, мониторить и изменять при большом числе ветвей. При хореографии каждый участник реагирует на события и создаёт собственные события без центрального координатора. Это работает для небольшого числа стабильных реакций, но полный процесс становится труднее обнаружить.
Выбирайте подход по сложности и ответственности процесса, а не по лозунгу. Если бизнесу нужно одно место, где видны сроки, компенсации и критерии завершения, оркестрация обычно понятнее.
Сбои, повторы и компенсации
Повтор подходит для временной технической ошибки, например кратковременного сетевого сбоя. Компенсация — новое бизнес-действие, которое отменяет или уравновешивает уже принятый факт: RefundPayment или ReleaseReservedStock. У него есть собственные права, инварианты, ошибки и аудит.
Компенсировать можно не всё. Некоторые действия необратимы, а некоторые требуют ручной проверки. Такие состояния нужно моделировать явно, а не прятать за общим словом «откат». Сага может создать событие о провале процесса, сохранив факты, которые уже произошли.
Чек-лист проверки саги
Сага готова к реализации, когда явно описаны стартовое событие, переходы состояния, команды, ожидаемые события, тайм-ауты и пути ошибок.
- Какой бизнес-процесс принадлежит саге?
- Что запускает и завершает его?
- Как коррелируются экземпляры?
- Какие шаги можно повторять?
- Какие ошибки требуют компенсации или человека?
- Как обрабатываются дубли и поздние сообщения?
- Видит ли оператор зависший экземпляр?
DDDesigner
Пример: выполнение заказа между контекстами
После OrderPlaced Сага выполнения заказа просит Inventory зарезервировать товар, а Payments — списать деньги. Она хранит идентификаторы заказа и процесса, ждёт оба результата и корректно обрабатывает повторные сообщения. Если оплата не прошла после резервирования, сага отправляет ReleaseStock и фиксирует компенсацию. Если провайдер недоступен дольше установленного срока, процесс переходит в состояние ручной проверки, а не делает вид, что транзакция откатилась. После успеха Inventory, Payments и Shipping сага отправляет ScheduleDelivery и публикует FulfillmentCompleted.
Начать бесплатно