Saga
Saga — способ выполнить операцию, затрагивающую несколько микросервисов с разными базами данных, без единой распределённой транзакции. В монолите можно было бы обернуть всё в одну @Transactional (см. тему «Транзакции, ACID, уровни изоляции»), но в микросервисах у каждого сервиса своя база — единой транзакции через них не бывает.
Идея: разбить операцию на шаги, и для каждого шага предусмотреть компенсирующее действие, если что-то пошло не так дальше по цепочке:
Копнуть глубже
Два способа координации Saga:
- Хореография (choreography) — каждый сервис публикует событие о результате своего шага, следующий сервис реагирует на это событие самостоятельно (см. тему «Событие vs команда») — нет центрального координатора, сервисы “танцуют” по очереди, реагируя друг на друга.
- Оркестрация (orchestration) — есть отдельный сервис-дирижёр (Saga Orchestrator), который явно командует каждым шагом и решает, когда запускать компенсацию.
| Хореография | Оркестрация | |
|---|---|---|
| Связанность | низкая (события) | выше (явные команды от дирижёра) |
| Видимость всего процесса | размазана по сервисам, сложнее отследить | в одном месте, легче понять и отладить |
| Подходит для | простых саг с малым числом шагов | сложных саг с условной логикой и множеством шагов |
Главная сложность Saga — компенсирующие действия не всегда возможны идеально. “Вернуть деньги” — относительно просто, но если шаг был “отправить письмо клиенту” — отменить это уже нельзя, письмо отправлено. Поэтому проектирование саги требует продумывать заранее, какие шаги обратимы, а какие нет, и в каком порядке их выполнять, чтобы необратимые шаги шли последними, когда вероятность отката уже минимальна.
• разницу хореографии и оркестрации (если дошёл до 2-го слоя).