Ответ
Традиционные ACID-транзакции (например, двухфазный коммит) плохо подходят для микросервисов из-за сильной связанности и блокировок. Вместо них используются паттерны, основанные на принципе конечной согласованности (eventual consistency).
Saga Pattern
- Идея: Длинная транзакция разбивается на серию локальных транзакций в каждом сервисе. Если какой-то шаг не удается, выполняются компенсирующие транзакции для отмены предыдущих шагов.
- Реализации:
- Оркестрация (Orchestration): Центральный сервис-координатор управляет процессом, вызывая сервисы по очереди.
- Хореография (Choreography): Сервисы общаются через события (events). Каждый сервис подписывается на события других и реагирует на них, запуская свою локальную транзакцию.
Two-Phase Commit (2PC)
- Идея: Классический алгоритм с координатором и участниками.
- Фаза 1 (Prepare): Координатор спрашивает всех участников, готовы ли они к коммиту. Участники блокируют ресурсы.
- Фаза 2 (Commit/Abort): Если все готовы, координатор отправляет команду
commit
. Если хоть один не готов — командуabort
.
- Недостатки: Считается анти-паттерном в микросервисах из-за низкой производительности, блокировок и наличия единой точки отказа (координатора).
- Идея: Классический алгоритм с координатором и участниками.
Outbox Pattern
- Идея: Обеспечивает надежную доставку сообщений/событий. Вместо того чтобы сразу отправлять событие в брокер сообщений после изменения данных в БД, сервис выполняет 2 действия в рамках одной локальной транзакции:
- Сохраняет бизнес-сущность в свою таблицу.
- Сохраняет событие в специальную таблицу
outbox
.
- Отдельный процесс (или сам сервис) асинхронно читает события из
outbox
и надежно доставляет их в брокер сообщений (Kafka, RabbitMQ). Это гарантирует, что событие не будет потеряно и будет отправлено только если бизнес-транзакция успешно завершилась.
- Идея: Обеспечивает надежную доставку сообщений/событий. Вместо того чтобы сразу отправлять событие в брокер сообщений после изменения данных в БД, сервис выполняет 2 действия в рамках одной локальной транзакции:
Event Sourcing
- Идея: Состояние приложения не хранится в его текущем виде. Вместо этого хранится полная последовательность событий (фактов), которые привели к этому состоянию. Текущее состояние можно восстановить, "проиграв" все события. Этот подход хорошо сочетается с хореографической сагой.
Вывод: Для большинства микросервисных систем Saga и Outbox Pattern являются наиболее предпочтительными и популярными решениями. В Go для реализации саг часто используют готовые фреймворки, например, dtm-labs/dtm
.