Что такое паттерн SAGA и как он решает проблему распределённых транзакций?

Ответ

Паттерн SAGA — это подход к управлению данными в распределённых системах (например, в микросервисной архитектуре), который обеспечивает целостность данных без использования традиционных ACID-транзакций с блокировками.

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

Пример: Оформление заказа

Бизнес-процесс: Создать заказ -> Списать деньги -> Зарезервировать товар.

  1. Шаг 1 (Сервис Заказов): Создает заказ в статусе PENDING. Публикует событие OrderCreated.
  2. Шаг 2 (Сервис Платежей): Получает событие OrderCreated, списывает деньги с клиента. Публикует событие BillingSuccess.
  3. Шаг 3 (Сервис Склада): Получает событие BillingSuccess, резервирует товар. Публикует StockReserved.
  4. Завершение: Заказ успешно оформлен.

Что если шаг 3 не удался (товара нет на складе)?

  • Сервис Склада публикует событие StockReservationFailed.
  • Сервис Платежей ловит это событие и выполняет компенсирующую транзакцию: возвращает деньги клиенту.
  • Сервис Заказов также ловит событие и меняет статус заказа на FAILED.

Два основных способа реализации саги:

  1. Хореография (Choreography): Сервисы общаются напрямую через события, без центрального координатора. Каждый сервис знает, на какое событие реагировать. (Пример выше — хореография).
  2. Оркестрация (Orchestration): Существует центральный сервис-оркестратор, который управляет всем процессом. Он отправляет команды каждому сервису и ждет ответа, решая, какой шаг выполнить следующим.

Преимущества:

  • Слабая связанность: Сервисы не зависят друг от друга напрямую.
  • Высокая доступность: Отсутствие блокировок между сервисами.
  • Масштабируемость: Каждый сервис может масштабироваться независимо.

Сложности:

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