两阶段提交(2PC)算法中,协调者/主节点何时保存自身数据?
2PC多节点事务提交一致性问题解答
场景回顾
- 初始状态:数据库A、B、C中
value(key=x) = 55 - 事务需求:将x的值改为56,需以全有或全无的原子性方式同步到三个节点
你的两种猜想的问题分析
猜想一:A收B、C确认后提交自身再标记完成
这种方式跳过了2PC核心的「预提交」阶段,直接让节点提交变更。此时A提交后,B、C可能还未收到最终提交指令,就会出现A的x是56,B/C的x还是55的不一致状态,违背了事务的原子性要求。猜想二:B等A确认收到回执后再提交
这种设计会导致严重的阻塞问题:如果A提交自身后宕机,无法给B发送确认回执,B会一直处于等待状态;同时如果A已经提交,B未提交,依然会出现A是56、B是55的不一致,同样不符合原子性要求。
标准2PC的正确执行流程(解决一致性问题)
2PC通过「准备阶段」和「提交阶段」的分阶段执行,从根本上避免了中间状态的不一致:
1. 准备阶段(Prepare Phase)
- 客户端将事务请求发往A,A作为协调者,B、C作为参与者
- A向B、C发送
Prepare指令,内容为“将key=x的值修改为56” - 每个参与者(B、C)执行以下操作:
- 记录事务日志(用于故障恢复)
- 锁定key=x的资源(防止其他事务修改)
- 验证自身是否能完成该修改(比如无锁冲突、资源充足)
- 向A回复
Yes(确认可以提交)或No(无法提交)
- 同时,A自身也执行本地预提交操作:记录日志、锁定x,不真正提交数据变更
2. 提交阶段(Commit Phase)
- 情况一:所有参与者回复
Yes- A向B、C发送
Commit指令 - 每个参与者收到指令后,执行真正的数据提交(将x从55改为56),释放锁定的资源,然后向A回复提交确认
- A收到所有参与者的确认后,执行自身的数据提交,标记事务完成
- A向B、C发送
- 情况二:任意参与者回复
No- A向所有参与者发送
Rollback指令 - 每个参与者回滚事务,释放资源,回复回滚确认
- A自身也回滚事务,标记事务失败
- A向所有参与者发送
为什么标准流程能避免不一致?
- 在准备阶段,所有节点都只做预提交,不会真正修改数据,此时读取任何节点的x都是55,不存在中间不一致
- 只有当协调者确认所有节点都能提交后,才会触发全局提交,所有节点几乎同时执行最终变更(网络延迟带来的短暂差异属于最终一致范畴,且2PC保证的是原子性:要么全节点完成变更,要么全节点回滚到初始状态)
- 若出现节点宕机或网络故障,各节点可通过事务日志回放,恢复到正确的事务状态,最终达成一致
内容的提问来源于stack exchange,提问作者user2967799
相关产品推荐
相关产品推荐

