Паттерн Saga

Паттерн saga — это способ сохранять согласованность данных между сервисами, когда ни одна транзакция базы данных не может охватить их все. Вместо одного атомарного коммита, который либо полностью проходит, либо полностью откатывается, saga разбивает работу на последовательность локальных транзакций, каждая из которых коммитится независимо в своём сервисе, и связывает каждый шаг с компенсирующим действием, семантически отменяющим его, если следующий шаг не удался. Повышение тарифа в типичном SaaS-бэкенде хорошо это показывает: списать с карты, обновить права доступа, выделить дополнительные места, отправить чек. Четыре сервиса, четыре отдельные базы, ни одной общей транзакции. Если выделение мест сорвалось после успешного списания, откатить списание в смысле базы данных невозможно — деньги ушли. Компенсирующее действие здесь — возврат, то есть новая прямая транзакция, оставляющая обе записи на месте. Это и есть определяющее свойство, которое чаще всего понимают неверно: компенсация семантическая, а не буквальная. Стилей координации два. При хореографии каждый сервис публикует событие, а следующий на него реагирует; это сохраняет слабую связанность, но размазывает поток по кодовой базе, так что нигде нет одного места, описывающего, что транзакция на самом деле делает. При оркестрации один компонент отвечает за вызов каждого шага и запуск компенсаций при сбое; это делает поток читаемым и тестируемым ценой того, что сам компонент должен быть надёжно сохраняем — он не имеет права потерять состояние посреди саги. Большинство команд начинают с хореографии на двух-трёх шагах и переходят к оркестрации, когда последовательность растёт или когда кому-то приходится её отлаживать. Саги меняют атомарность на доступность, и плата за это — видимость промежуточных состояний: какое-то время клиент уже списан, но мест ещё не получил. Систему нужно проектировать так, чтобы такое состояние было понятным, а не неожиданным. Каждый шаг также обязан быть идемпотентным, потому что повторы гарантированы, а компенсирующее действие, выполненное дважды, не должно вернуть деньги дважды. Практическое замечание: заведите для каждой саги сохраняемую запись состояния с идентификатором, текущим шагом и конечным исходом, а компенсации сделайте идемпотентными по этому идентификатору. В продакшене саги ломаются не потому, что компенсацию трудно написать, а потому, что никто не может ответить, на каком шаге застряла транзакция.

Похожие термины

Ещё термины: Инструменты разработки