Распределённые транзакции: Saga (оркестрация и хореография), 2PC
↑ 8.3 Микросервисы и распределённые системы · ← Предыдущая · → Следующая
Зачем это на собесе
Ключевой вопрос микросервисов: «как обеспечить согласованность без общей транзакции».
Объяснение
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.
Практика
- Реализуйте сагу заказа с оплатой и резервом, включая компенсацию.
- Сымитируйте сбой на каждом шаге и проверьте итоговое состояние.
- Добавьте мониторинг зависших саг по таймауту.
Вопросы с ответами
Почему не 2PC в микросервисах?
Блокирует ресурсы, создаёт единую точку отказа и не масштабируется; связывает сервисы и БД технически.
Оркестрация или хореография?
Хореография — для коротких простых потоков; оркестрация — для сложных процессов с явным управлением.
Что такое компенсирующая транзакция?
Действие, семантически отменяющее эффект выполненного шага.