Распределённые транзакции: Saga (оркестрация и хореография), 2PC

↑ 8.3 Микросервисы и распределённые системы · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: senior

Зачем это на собесе

Ключевой вопрос микросервисов: «как обеспечить согласованность без общей транзакции».

Объяснение

2PC (Two-Phase Commit): координатор просит участников подготовиться (prepare), затем подтвердить (commit). Даёт атомарность, но блокирует ресурсы, зависит от координатора и плохо масштабируется; в облачных микросервисах не используется (MSDTC).

Saga — последовательность локальных транзакций; при сбое выполняются компенсирующие действия.

sequenceDiagram
  participant O as Orders
  participant P as Payments
  participant S as Stock
  O->>O: создать заказ (Pending)
  O->>P: списать оплату
  P-->>O: успех
  O->>S: зарезервировать товар
  S-->>O: нет в наличии
  O->>P: компенсация: вернуть оплату
  O->>O: заказ Cancelled
ВидКакПлюсы/минусы
Хореографиясервисы реагируют на события друг друга, координатора нетпростота для 2–3 шагов; сложно понять общий поток
Оркестрацияоркестратор (state machine) управляет шагамиявный процесс, проще отладка; дополнительный компонент
// Оркестрация: MassTransit state machine
Initially(When(OrderSubmitted).Then(...).TransitionTo(AwaitingPayment).Publish(ctx => new ChargePayment(ctx.Saga.OrderId)));
During(AwaitingPayment,
    When(PaymentSucceeded).TransitionTo(Reserving).Publish(...),
    When(PaymentFailed).TransitionTo(Cancelled));
During(Reserving, When(StockReservationFailed).Publish(ctx => new RefundPayment(...)).TransitionTo(Cancelled));

Свойства саг: нет изоляции (промежуточные состояния видны), нужны семантические блокировки («Pending»), идемпотентные шаги и компенсации, надёжная публикация (outbox), таймауты.

Нюансы и подводные камни

  • Компенсация не всегда возможна («письмо отправлено»): продумывайте порядок — необратимые шаги в конце.
  • Шаг может выполниться повторно — идемпотентность обязательна.
  • Долгие саги требуют хранения состояния и мониторинга «зависших» процессов.
  • Понимайте, что «отмена» — тоже бизнес-событие.
  • Не ищите ACID там, где допустима eventual consistency.

Практика

  1. Реализуйте сагу заказа с оплатой и резервом, включая компенсацию.
  2. Сымитируйте сбой на каждом шаге и проверьте итоговое состояние.
  3. Добавьте мониторинг зависших саг по таймауту.

Вопросы с ответами

Связанные темы