System Design Space
Граф знанийНастройки

Обновлено: 24 июня 2026 г. в 13:28

Распределённые транзакции: 2PC и 3PC

сложный

Практический разбор распределённых транзакций: координатор и участники, двухфазная и трёхфазная фиксация, блокировки, частичные сбои и альтернативы через Saga и транзакционный журнал исходящих событий.

Распределённые транзакции становятся болезненными там, где бизнес требует атомарности, а архитектура уже разделена на несколько сервисов и хранилищ.

В реальной инженерной работе эта глава помогает выбирать между двухфазной фиксацией, трёхфазной фиксацией, Saga и транзакционным журналом исходящих событий по границам домена, допустимым сбоям, блокировкам и цене координации.

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

Практическая польза главы

Практика проектирования

Учит выбирать транзакционный паттерн по границам домена и допустимым сбоям.

Качество решений

Помогает сравнить двухфазную фиксацию, трёхфазную фиксацию и Saga через задержку, блокировки и операционную сложность.

Аргументация на интервью

Дает ясную схему объяснения координатора, участников, точки фиксации и пути восстановления.

Риски и компромиссы

Делает явными блокировки, частичную фиксацию, семантику тайм-аутов и требования к идемпотентности.

Контекст

Консистентность и идемпотентность

Распределённые транзакции — один из способов удержать согласованность, но не единственный.

Открыть главу

нужна, когда важнее автономности отдельных сервисов. В таких сценариях важны , , , , и .

Перед выбором важно отделить от : это между атомарностью, доступностью и эксплуатационной ценой. На границах сервисов рядом часто появляется , чтобы сбой одного участника не забрал всю систему.

Цена проявляется при , , и . Поэтому рядом с протоколами фиксации часто проектируют , , , , , , и обработку .

Распределённые транзакции: двухфазная фиксация (2PC) и трёхфазная фиксация (3PC) нужны там, где бизнес-инвариант требует менять несколько независимых ресурсов как одно целое, а промежуточное состояние недопустимо. За эту атомарность платят задержками, блокировками и тем самым тяжёлым восстановлением после частичного отказа, ради которого протоколы и существуют.

Когда нужна распределённая транзакция

  • Одна бизнес-операция должна атомарно изменить несколько независимых ресурсов или сервисов, и разнести её на отдельные шаги нельзя.
  • Здесь не выдерживается даже временное расхождение состояния — промежуточный результат уже считается ошибкой.
  • Если фиксация прошла частично, цена ошибки переходит в финансы, регуляторику или то, что видит пользователь.

Как работает двухфазная фиксация (2PC)

2PC: двухфазная фиксация

Prepare -> голоса участников -> общее решение COMMIT/ABORT

Координатор собирает голоса участников и принимает единое решение: зафиксировать или отменить всю транзакцию.

Сильные стороны

  • Простая и понятная модель координации.
  • Чётко отделяет фазу подготовки от финального решения.

Риски

  • Блокировки при отказе координатора в неподходящий момент.
  • Высокая чувствительность к настройкам тайм-аутов и повторов.

Шаги протокола

Текущая команда

Нажмите Старт, чтобы проиграть протокол по шагам.

Координатор

Ожидает запуск

Команд от координатора: 0

Участники

3 участника

Шаг: 0 / 8

Заказы

участник A

Ожидание команд

Участвовал в шагах: 0

Платежи

участник B

Ожидание команд

Участвовал в шагах: 0

Склад

участник C

Ожидание команд

Участвовал в шагах: 0

Как работает трёхфазная фиксация (3PC)

3PC: трёхфазная фиксация

CanCommit -> PreCommit -> DoCommit

Добавляет промежуточную фазу PreCommit, чтобы уменьшить риск блокировок при проблемах координатора.

Сильные стороны

  • Снижает вероятность зависания в неопределённом состоянии.
  • Явно разделяет намерение зафиксировать изменения и финальную команду.

Риски

  • Больше сетевых раундов и более сложный конечный автомат.
  • Требует очень аккуратной настройки тайм-аутов и восстановления.

Шаги протокола

Текущая команда

Нажмите Старт, чтобы проиграть протокол по шагам.

Координатор

Ожидает запуск

Команд от координатора: 0

Участники

3 участника

Шаг: 0 / 12

Заказы

участник A

Ожидание команд

Участвовал в шагах: 0

Платежи

участник B

Ожидание команд

Участвовал в шагах: 0

Склад

участник C

Ожидание команд

Участвовал в шагах: 0

Альтернатива

Event-Driven Architecture

Чаще, чем кажется, Saga и транзакционный журнал исходящих событий дают лучший баланс, чем глобальная фиксация: блокировок нет, а согласованность достигается шагами.

Открыть главу

Компромиссы и альтернативы

Двухфазную фиксацию (2PC) проще объяснить и внедрить. Расплата приходит, когда координатор отказал после фазы подготовки: участники остаются заблокированными и держат ресурсы, пока он не вернётся.

Трёхфазная фиксация (3PC) убирает это зависание ценой ещё одного сетевого раунда — а вместе с ним растёт и конечный автомат протокола, который теперь надо корректно сопровождать.

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

В микросервисной архитектуре общая атомарная транзакция между сервисами почти всегда оказывается дороже и хрупче, чем кажется на схеме, — связность растёт, а отказ одного участника тормозит остальных.

Saga: оркестрация или хореография

Операция распадается на локальные шаги, каждый со своим компенсирующим действием. Атомарности нет — взамен исчезает глобальная блокировка и единая точка отказа в виде координатора.

Транзакционный журнал исходящих событий

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

Идемпотентные команды и согласование состояния

Когда повтор команды безопасен, частичный сбой перестаёт быть катастрофой: систему добивает до согласованного состояния фоновая сверка, а не ручной разбор.

Пересмотр границ домена

Самый дешёвый способ обойтись без распределённой транзакции — чтобы её не было. Сдвиньте границы агрегатов так, чтобы инвариант жил внутри одного сервиса.

Практический чеклист

  • Граница проведена явно: где действительно нужна атомарность, а где хватит согласованности в конечном итоге.
  • У координатора есть стратегия восстановления и долговечный журнал — после перезапуска он знает, какие транзакции висят в неопределённом состоянии.
  • Политики тайм-аутов проверены не на «основном сценарии», а на сетевых разделениях и задержках.
  • Повторная команда фиксации или отмены не ломает участника — обработка идемпотентна.
  • На спорный случай заложен бизнес-механизм компенсации и ручного разбора, а не только надежда на удачную автоматику.

Частая ошибка: вводить двухфазную фиксацию (2PC) между сервисами как «просто транзакцию», не посчитав заранее блокировки, модель повторов и цену восстановления, — и узнать о них уже в проде.

Источники

Связанные главы

Чтобы отмечать прохождение, включи трекинг в Настройки