Что происходит при ошибке в микросервисах в рамках саги
Что проверяют
Понимаете ли вы, что распределённой транзакции с откатом тут нет, и что сага меняет саму гарантию: вместо атомарности вы получаете согласованность в конечном счёте и обязаны написать компенсации руками.
Как отвечать
Сага это цепочка локальных транзакций, каждая коммитится в своём сервисе сразу. Если шаг упал, откатывать уже закоммиченное нечем, поэтому запускаются компенсирующие операции в обратном порядке: не rollback, а новое действие, отменяющее эффект по смыслу. Списание денег компенсируется возвратом, бронь отменой брони, отправленное письмо не компенсируется никак, и такие шаги ставят в конец цепочки.
Что сказать дальше:
- два стиля координации: хореография на событиях, где сервисы слушают друг друга, и оркестрация, где отдельный координатор хранит состояние саги и рассылает команды. Оркестрация дороже, зато её видно и можно отлаживать;
- состояние саги лежит в базе координатора, иначе после перезапуска непонятно, что компенсировать;
- бизнес-изменение и отправка сообщения должны попадать в одну локальную транзакцию, отсюда паттерн transactional outbox;
- шаги и компенсации идемпотентны, потому что доставка обычно at least once, и один возврат денег может приехать дважды;
- компенсация тоже падает: нужны повторы с выдержкой, очередь недоставленных сообщений и ручной разбор.
Где спотыкаются
Обещают откат распределённой транзакции и вспоминают двухфазный коммит как решение. В микросервисах он почти не применяется: держит блокировки всё время согласования, требует поддержки от всех участников, а недоступный координатор подвешивает систему.
Второе: забывают, что промежуточные состояния видны другим. Пока сага идёт, заказ уже создан, а оплата ещё нет, и соседний сервис успевает это прочитать. Отсюда семантические блокировки и явный статус в модели, а не молчаливое допущение, что данные согласованы.
Третье: рассказывают про логирование и мониторинг вместо механики. Интервьюер ждёт, кто именно инициирует компенсацию, где хранится состояние и что происходит, если упал сам координатор.