11.3 Саги
saga checkout(cart: Cart) -> Order {
Inventory.reserve(cart) undo r => Inventory.release(r.id)
-> Payments.charge(cart.total) undo p => Payments.refund(p.id)
-> Orders.create(cart, it)
}- Сага — последовательность шагов (синтаксис шагов как в цепочке §8.4); после шага МОЖЕТ стоять
undo x => компенсация, гдеx— результат шага. - Сага выполняется на узле с ролью, у которой есть
runs sagas. Вызов с другого узла перенаправляется туда. - Перед и после каждого шага состояние саги пишется в журнал встроенного хранилища. После сбоя узла другой узел роли продолжает сагу с последнего записанного шага.
- Ошибка шага
kзапускает компенсации завершённых шаговk−1 … 1в обратном порядке; затем сага возвращает исходную ошибку. - Компенсация повторяется с backoff до
SAGA_UNDO_RETRIESраз. Если она так и не удалась, сага получает статусstuck, возвращаетCompensationFailed{ cause, step }и видна в веб-интерфейсе (часть III) для ручного разбора. - Каждый шаг получает ключ идемпотентности
ctx.idempotencyKey = sagaId + номер шага; поэтому вызовы в шагах и компенсациях ДОЛЖНЫ быть@idempotent(иначе ошибка компиляции). - Тип вызова саги —
R | E | CompensationFailed | NetError, гдеE— ошибки шагов.
Связанные диагностики
См. также
Исходник: docs/spec/oxl-standard.md