Что такое двухфазный коммит (Two-Phase Commit, 2PC)?

Ответ

Двухфазный коммит (2PC) — это протокол для достижения атомарности распределённой транзакции. Он гарантирует, что все участники (например, несколько баз данных) либо все вместе зафиксируют изменения (commit), либо все вместе их откатят (rollback).

Протокол состоит из координатора и нескольких участников.

Две фазы:

  1. Фаза подготовки (Prepare Phase):

    • Координатор отправляет всем участникам команду PREPARE.
    • Каждый участник выполняет свою часть транзакции, но не фиксирует её окончательно. Он записывает результат во временное хранилище (лог) и готовится к фиксации.
    • Если участник готов, он отвечает координатору VOTE_COMMIT. Если произошла ошибка (например, конфликт блокировок), он отвечает VOTE_ABORT.
  2. Фаза фиксации (Commit/Rollback Phase):

    • Сценарий успеха: Если координатор получил VOTE_COMMIT от всех участников, он рассылает им команду GLOBAL_COMMIT. Участники, получив её, фиксируют свои изменения.
    • Сценарий провала: Если хотя бы один участник прислал VOTE_ABORT (или не ответил за таймаут), координатор рассылает всем команду GLOBAL_ABORT. Участники откатывают свои изменения.

Проблемы 2PC:

  • Блокировка: Это самый большой недостаток. Если координатор выходит из строя после фазы подготовки, но до рассылки решения (commit/abort), участники остаются в неопределенном состоянии. Они не знают, что делать, и вынуждены блокировать ресурсы до восстановления координатора.
  • Производительность: Протокол является синхронным и требует нескольких раундов обмена сообщениями, что делает его медленным.

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

  • Three-Phase Commit (3PC): Усложненная версия 2PC, которая решает проблему блокировки, но является более сложной в реализации.
  • Паттерн Saga: Обеспечивает согласованность данных через серию локальных транзакций, где каждая транзакция имеет компенсирующее действие для отката. Saga предпочитает доступность строгой согласованности и лучше подходит для долгоживущих транзакций.