Прямой ответ
Two-phase commit (2PC) — протокол обеспечения согласованности в распределенных транзакциях (2PC — «2PC» — 2PC — incident — «двухфазная фиксация» — 2PC), зачем: сильная согласованность (2PC — «сильная согласованность» — 2PC — incident — «согласованность» — 2PC — postgres — «все или ничего» — 2PC — distributed); фазы 2PC (2PC — «две фазы» — 2PC): (1) Фаза 1: Prepare (2PC — «подготовка» — 2PC — incident — «координатор спрашивает участников» — 2PC — postgres — «готовы ли» — 2PC — distributed — «prepare» — 2PC — «участники отвечают да/нет» — 2PC — 2PC); (2) Фаза 2: Commit (2PC — «фиксация» — 2PC — incident — «координатор принимает решение» — 2PC — postgres — «commit или rollback» — 2PC — distributed — «commit» — 2PC — «участники фиксируют или откатывают» — 2PC — 2PC); участники 2PC (2PC — «участники» — 2PC): (1) Координатор (2PC — «координатор» — 2PC — incident — «управляет транзакцией» — 2PC — postgres — «координатор» — 2PC — distributed — «координатор» — 2PC — «принимает решение» — 2PC — 2PC); (2) Участники (2PC — «участники» — 2PC — incident — «выполняют операции» — 2PC — postgres — «участники» — 2PC — distributed — «участники» — 2PC — «готовы/не готовы» — 2PC — 2PC); преимущества (2PC): (1) Сильная согласованность (2PC — «сильная согласованность» — 2PC — incident — «согласованность» — 2PC — postgres — «все или ничего» — 2PC — distributed — «сильная» — 2PC); (2) Атомарность (2PC — «атомарность» — 2PC — incident — «все или ничего» — 2PC — postgres — «атомарность» — 2PC — distributed — «атомарность» — 2PC); недостатки (2PC): (1) Блокировки (2PC — «блокировки ресурсов» — 2PC — incident — «блокировки» — 2PC — postgres — «блокировки» — 2PC — distributed — «блокировки» — 2PC); (2) Единая точка отказа (2PC — «координатор — единая точка отказа» — 2PC — incident — «единая точка отказа» — 2PC — postgres — «координатор» — 2PC — distributed — «единая точка» — 2PC); (3) Производительность (2PC — «медленнее локальных транзакций» — 2PC — incident — «медленнее» — 2PC — postgres — «производительность» — 2PC — distributed — «производительность» — 2PC); когда использовать (2PC): сильная согласованность (2PC — «когда нужна сильная согласованность» — 2PC — incident — «сильная согласованность» — 2PC — postgres — «2PC» — 2PC — distributed — 2PC), финансовые транзакции (2PC — «финансы» — 2PC — incident — «финансы» — 2PC — postgres — «2PC» — 2PC — distributed — 2PC); антипаттерны: игнорировать недостатки (2PC — «игнорировать блокировки» — 2PC — incident — «проблемы» — 2PC — postgres — «понимать недостатки» — 2PC), неправильное использование (2PC — «неправильно используется» — 2PC — incident — «проблемы» — 2PC — postgres — «правильное использование» — 2PC).
Практика: 2PC в PostgreSQL
PREPARE TRANSACTION (2PC — BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; PREPARE TRANSACTION 'tx1'; (2PC — «prepare» — 2PC — postgres — «подготовка» — 2PC — distributed — 2PC); COMMIT PREPARED (2PC — COMMIT PREPARED 'tx1'; (2PC — «commit» — 2PC — postgres — «фиксация» — 2PC — distributed — 2PC); ROLLBACK PREPARED (2PC — ROLLBACK PREPARED 'tx1'; (2PC — «rollback» — 2PC — postgres — «откат» — 2PC — distributed — 2PC); XA в MySQL (2PC — XA START 'tx1'; UPDATE accounts SET balance = balance - 100 WHERE id = 1; XA END 'tx1'; XA PREPARE 'tx1'; XA COMMIT 'tx1'; (2PC — «XA» — 2PC — postgres — «MySQL» — 2PC — distributed — MySQL).
Практический сценарий: использование 2PC для распределенной транзакции
Контекст: распределенная система (postgres — нужно обеспечить согласованность (incident — 2PC), боль: согласованность (2PC — «согласованность в распределенных системах» — 2PC — incident — «согласованность» — 2PC — postgres); решение — two-phase commit: (1) координатор (2PC — управляет транзакцией (2PC — «координатор» — 2PC — postgres — «координатор» — 2PC — distributed — 2PC); (2) участники (2PC — выполняют операции (2PC — «участники» — 2PC — postgres — «участники» — 2PC — distributed — 2PC); (3) фаза prepare (2PC — PREPARE TRANSACTION 'tx1'; (2PC — postgres — «prepare» — 2PC — distributed — 2PC); (4) фаза commit (2PC — COMMIT PREPARED 'tx1'; (2PC — postgres — «commit» — 2PC — distributed — 2PC); (5) сильная согласованность (2PC — «все или ничего» — 2PC — postgres — «согласованность» — 2PC — distributed — 2PC); результат: транзакция выполнена (2PC — «согласованно» — 2PC — incident — «согласованность» — 2PC — postgres — «атомарно» — 2PC — «изолированно» — 2PC); вывод: two-phase commit решили задачу (сильная согласованность — 2PC — ADR — «игнорировать недостатки» — антипаттерн — postgres — понимать недостатки — 2PC — техдолг).
FAQ
Что такое two-phase commit и какие у него фазы?
Two-phase commit (2PC — протокол (2PC — «2PC» — 2PC — incident — «двухфазная фиксация» — 2PC — postgres — distributed); фазы (2PC): Prepare (2PC — «подготовка» — 2PC — incident — «координатор спрашивает участников» — 2PC — postgres — PREPARE TRANSACTION (2PC — distributed — 2PC), Commit (2PC — «фиксация» — 2PC — incident — «координатор принимает решение» — 2PC — postgres — COMMIT PREPARED (2PC — distributed — 2PC); «игнорировать фазы» — антипаттерн (проблемы — postgres — понимать фазы — 2PC — ADR — техдолг).
Какие преимущества и недостатки 2PC? Преимущества (2PC): сильная согласованность (2PC — «сильная согласованность» — 2PC — incident — «согласованность» — 2PC — postgres — distributed), атомарность (2PC — «атомарность» — 2PC — incident — «все или ничего» — 2PC — postgres — distributed); Недостатки (2PC): блокировки (2PC — «блокировки ресурсов» — 2PC — incident — «блокировки» — 2PC — postgres — distributed), единая точка отказа (2PC — «координатор — единая точка отказа» — 2PC — incident — «единая точка» — 2PC — postgres — distributed), производительность (2PC — «медленнее локальных транзакций» — 2PC — incident — «медленнее» — 2PC — postgres — distributed); «игнорировать недостатки» — антипаттерн (проблемы — postgres — понимать недостатки — 2PC — ADR — техдолг).
Как использовать 2PC в PostgreSQL и MySQL?
PostgreSQL (2PC — BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; PREPARE TRANSACTION 'tx1'; COMMIT PREPARED 'tx1'; (2PC — postgres — «PostgreSQL» — 2PC — distributed — 2PC); MySQL (2PC — XA START 'tx1'; UPDATE accounts SET balance = balance - 100 WHERE id = 1; XA END 'tx1'; XA PREPARE 'tx1'; XA COMMIT 'tx1'; (2PC — postgres — «MySQL» — 2PC — distributed — MySQL — 2PC); «не использовать 2PC» — антипаттерн (проблемы — postgres — 2PC важен — 2PC — ADR — техдолг).
Когда использовать 2PC и какие альтернативы существуют? Когда (2PC — сильная согласованность (2PC — «когда нужна сильная согласованность» — 2PC — incident — «сильная согласованность» — 2PC — postgres — «2PC» — 2PC — distributed — 2PC), финансовые транзакции (2PC — «финансы» — 2PC — incident — «финансы» — 2PC — postgres — «2PC» — 2PC — distributed — 2PC); Альтернативы (2PC — Saga (2PC — «Saga» — 2PC — incident — «eventual consistency» — 2PC — postgres — distributed — Saga), Outbox (2PC — «Outbox» — 2PC — incident — «eventual consistency» — 2PC — postgres — distributed — Outbox); «игнорировать альтернативы» — антипаттерн (проблемы — postgres — альтернативы важны — 2PC — ADR — техдолг).
Источники: Wikipedia (2PC), PostgreSQL docs (prepare transaction), MySQL docs (XA statements) — ссылки в шапке.