Перейти к основному содержимому

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

2PC (Two-Phase Commit) – протокол для гарантии атомарности распределенных транзакций
Цель: все участники либо фиксируют изменения, либо откатывают их как единое целое, даже при сбоях.
Это критично для согласованности данных в распределенных системах.

  • Атомарность – "Всё или ничего". Либо выполняются все операции транзакции, либо ни одна

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

Роли участников

  1. Координатор (Coordinator): управляет процессом, принимает решение

    • Центральный управляющий компонент
    • Инициирует протокол 2PC
    • Принимает решение (Commit/Abort) на основе голосования ресурсов
    • Отвечает за уведомление ресурсов о решении и управление восстановлением при сбоях

    Примеры:

    • Транзакционные менеджеры (Atomikos, Narayana)
    • СУБД-координатор (PostgreSQL XA, Oracle XA)
    • Системные оркестраторы (Tuxedo, IBM CICS)
  2. Ресурсы (Участники): выполняют локальные операции, голосуют

    • Системы или сервисы, управляющие данными (например, БД)
    • Выполняют локальную работу транзакции ("до" коммита)
    • Голосуют "Да" (готов к коммиту) или "Нет" (не готов) на фазе Prepare
    • Выполняют финальную команду (Commit/Abort) от координатора

    Примеры:

    • Базы данных (Oracle, MySQL, PostgreSQL)
    • Очереди сообщений (IBM MQ, Apache ActiveMQ)
    • Legacy-системы (банковские мейнфреймы, ERP SAP)
  • Стандарт XA: для взаимодействия координатора и ресурсов в 2PC. Определяет API для prepare, commit, rollback

Фазы

Фаза 1: Prepare (Подготовка)

  1. Координатор → Ресурсы: координатор рассылает ресурсам команду prepare (запрос голосования)
  2. Ресурсы:
    • Проверяют возможность коммита своей части транзакции (проверка ограничений, конфликтов, запись в локальный лог для восстановления)
    • Блокируют данные (локальные блокировки)
    • Проверяют возможность коммита
  3. Голосование ресурсов (отправляют координатору):
    • vote_commit (если готов)
    • vote_abort (если не готов) и выполняют локальный откат

Фаза 2: Commit (Фиксация) / Abort (Отмена)

Если все vote_commit:

  1. Координатор → Ресурсы: рассылает команду commit
  2. Ресурсы фиксируют изменения, разблокируют данные
    • Физически фиксируют изменения данных
    • Освобождают блокировки
    • Отправляют координатору ack (подтверждение)
  3. Координатор, получив все ack, завершает транзакцию

Если хотя бы один vote_abort (или таймаут):

  1. Координатор → Ресурсы: abort (или rollback)
  2. Ресурсы откатывают изменения по журналу
    • Откатывают свою часть транзакции
    • Освобождают блокировки
    • Отправляют координатору ack
  3. Координатор, получив все ack, завершает транзакцию (как отмененную)

Сценарии работы

Успешная Транзакция

  1. Клиент делает перевод 100 руб со Счета А (Ресурс 1) на Счет Б (Ресурс 2)
  2. Координатор шлет prepare обоим банкам
  3. Банк А: Проверяет наличие 100 руб, блокирует их, голосует "Да"
    Банк Б: Проверяет возможность зачисления, голосует "Да"
  4. Координатор шлет commit
  5. Банк А: Списывает 100 руб, освобождает блокировку
    Банк Б: Зачисляет 100 руб. Оба шлют ack
  6. Клиент получает подтверждение

Отказ Ресурса и Восстановление

  • Сбой во время Prepare: Ресурс не ответил
    Координатор трактует как vote_abort "Нет" → Откат всех

  • Сбой Ресурса после vote_commit: Ресурс упал до получения commit

    • При восстановлении ресурс смотрит в свой лог: prepare есть, а commit/abort нет
    • Ждёт команду координатора (состояние "in doubt")
  • Сбой Координатора после записи решения:

    • После записи решения → При рестарте пересылает решение ресурсам
    • До записи решения → Ресурсы остаются заблокированными до ручного вмешательства

Применение

  • Legacy-системы: интеграция старых монолитных систем (особенно БД) через стандарт XA
    Пример: Перевод денег между двумя разными legacy-банковскими системами, каждая со своей БД
  • Где критична строгая согласованность в реальном времени на уровне отдельных транзакций между разными системами (счета, ленты транзакций, бухгалтерия). Часто используется внутри монолитных или тесно интегрированных систем
  • Системы, где ресурсы (БД, очереди) поддерживают интерфейс XA для участия в транзакциях под управлением внешнего TM

Плюсы и минусы

Плюсы

  • Четкое разделение фаз и ролей
  • Ресурсами могут быть разные БД/системы, если они поддерживают XA-интерфейс
  • Стандартизация (XA): Широко поддерживаемый стандарт для распределенных транзакций

Минусы

  • Ресурсы блокируются на всей фазе Prepare до финального решения. Убивает производительность и масштабируемость, создает риск взаимоблокировок
  • Координатор и ресурсы ожидают ответов друг от друга, увеличивая задержку
  • Координатор — единая точка отказа. Его сбой может "заморозить" ресурсы
  • Процедуры восстановления после сбоев координатора или ресурсов сложны в реализации и поддержке
  • Каждая транзакция требует синхронного взаимодействия со всеми ресурсами через координатор. Растет нагрузка и задержка

Почему не подходит для микросервисов

  1. Микросервисы должны быть независимыми (автономными). Координатор создаёт централизованную зависимость
  2. Блокировки: Долгие lock'и снижают отзывчивость (latency ↑, throughput ↓)
  3. SPOF (Single Point of Failure): Сбой координатора парализует систему
  4. Сценарии восстановления после сбоев координатора сложны и могут привести к длительным блокировкам данных в микросервисах ("in doubt"), что неприемлемо для высокодоступных систем
  5. Синхрон 2PC ограничивает throughput, что противоречит идее горизонтального масштабирования микросервисов
  6. CAP-теорема: При сетевом разделе (Partition) 2PC жертвует доступностью (Availability) в пользу согласованности (Consistency)

Материалы

  1. Управление транзакциями в базах данных
  2. Способы управления транзакциями в распределённых ИС. Механизм двухфазной фиксации транзакций
  3. Сравнение подходов к реализации распределённых транзакций для микросервисов
  4. Двухфазный коммит и будущее распределённых систем
  5. Распределённые транзакции в микросервисах: от SAGA до Two-Phase Commit
  6. Двухфазная фиксация в распределённых транзакциях
  7. Наиболее используемые шаблоны проектирования распределённых систем
  8. Распределённые транзакции для самых маленьких
  9. Проблемы согласованности данных в микросервисах и их решение
  10. Проблематика распределённых транзакций в контексте микросервисной архитектуры
  11. Согласованность данных в высоконагруженных системах
  12. Архитектура больших данных: 5 шаблонов проектирования распределённых систем
  13. Топ-5 архитектурных паттернов для распределённых систем

Видео

  1. Распределенные транзакции / Что выбрать? Saga или 2PC? / Как подружить микросервисы
  2. Почему отправка сообщения в Кафку — это двухфазный коммит
  3. Масштабируемая архитектура для систем обработки платежей // курс «Microservice Architecture»
  4. Введение в распределённые системы. Протокол 2PC
  5. Распределенные системы. Паттерны распределенных систем. Часть 2

Книги