← 中文资源

简体中文版本

两阶段提交

两阶段提交协调多个数据库的原子提交,代价是阻塞、协调者故障和运维复杂性。

阅读英文原文

先准备,再提交

协调者向所有参与者发送准备请求。每个参与者写下足够信息以便之后提交或回滚,获取必要锁,并投票同意或拒绝。如果所有参与者同意,协调者持久记录提交决定并通知所有人;任何一个拒绝,所有人回滚。决定点是协调者的持久日志;记录提交后,事务最终必须在各处提交。

BEGIN;
-- 在本数据库执行工作
PREPARE TRANSACTION 'order-42';
-- 协调者决定后:
COMMIT PREPARED 'order-42';
-- 或:
ROLLBACK PREPARED 'order-42';

已准备事务可在 pg_prepared_xacts 中看到。已准备但与协调者失联的参与者持有锁且无法自行决定,这就是阻塞故障模式。运维手册必须检测悬而未决的事务,并依据协调者的决定解决,而不是猜测。

协调者是单点

如果协调者在部分参与者准备后、记录决定前崩溃,参与者会等待。复制协调者加共识日志能降低风险,但不能消除延迟和持锁成本。协议假设参与者可以短暂不可用;长时间故障可能耗尽锁表并阻塞无关工作。

何时使用

当多个事务资源必须原子提交,且可接受可用性代价时,使用两阶段提交,例如数据库迁移或具有可靠协调者的紧密耦合系统。优点是原子性;缺点是阻塞、锁竞争和恢复复杂。与 Saga 相比,2PC 原子性更强,但可用性更低、耦合更紧。多数微服务工作流应优先使用本地事务加 outbox 或 Saga,除非业务确实需要分布式原子提交。