АрхитектураАрхитектура ПОАрхитектор распределённых систем

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

Бизнес-операция проходит через несколько автономных сервисов, а общей транзакции между ними нет. Какой механизм позволяет согласовать её частичное выполнение?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

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

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

Исторический контекст

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

Подход переносит ответственность с инфраструктурного отката на бизнес-логику. Вместо требования выполнить всё атомарно система описывает, как корректно исправить последствия уже выполненных действий.

Постановка проблемы

Рассмотрим оформление заказа: сервис заказа создаёт заказ, сервис склада резервирует товар, платёжный сервис списывает деньги, а сервис доставки создаёт отправление. У этих сервисов могут быть разные базы данных, независимые релизы и временная недоступность.

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

Подробное решение

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

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

Оркестрация обычно лучше подходит для сложного процесса: состояние саги, тайм-ауты и причины отказов видны в одном месте. Цена — дополнительный компонент и риск превратить его в чрезмерно умный центр бизнес-логики. Хореография уменьшает централизацию, но при большом числе участников усложняет понимание потока, наблюдаемость и изменение порядка шагов.

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

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

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

Главный компромисс — согласованность в конечном итоге вместо мгновенной глобальной атомарности. Сага подходит, когда бизнес допускает промежуточные состояния и имеет осмысленные компенсации; если же любое частичное выполнение недопустимо, следует пересмотреть границу операции или применить другой способ координации.

Ситуация из практики

В интернет-магазине после списания оплаты сервис доставки иногда был недоступен. Рассматривались три варианта. Распределённая транзакция дала бы более строгую атомарность, но связала бы базы и доступность всех сервисов, а также плохо подходила бы для внешнего платёжного провайдера. Хореография уменьшила бы роль центрального компонента, но усложнила бы контроль переходов и диагностику. Ожидание восстановления доставки без компенсации оставляло бы деньги и товар в неопределённом состоянии.

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

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

Что кандидаты часто упускают

  1. Можно ли считать сагу гарантией атомарности?

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

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

  1. Почему одной компенсации недостаточно для надёжной саги?

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

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

  1. Когда сага является плохим выбором?

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

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