分布式系统【六、两阶段提交(2PC)与三阶段提交(3PC)协议详解】
两阶段提交(2PC)与三阶段提交(3PC)协议详解
系列专题第六篇 · 分布式系统基础指南
一、引言
在分布式系统中,一致性问题不仅出现在副本复制(如 Raft、Paxos),也出现在 分布式事务 中。
一个事务可能跨越多个数据库或服务节点,例如:
电商系统中的「下单 → 扣库存 → 扣余额 → 生成订单」。金融系统中的「账户转账」。
这些操作必须遵循 ACID 中的一致性:要么全部成功,要么全部失败。
为解决跨节点事务一致性问题,业界提出了 两阶段提交(2PC) 和 三阶段提交(3PC) 协议。
二、2PC 协议(Two-Phase Commit)
2PC 是分布式事务的经典协议,分为两个阶段:准备阶段(Prepare) 和 提交阶段(Commit)。
阶段一:准备(Voting / Prepare)
协调者(Coordinator) 向所有参与者(Participant)发送事务请求。每个参与者执行事务操作(如写入数据库),但不提交,只写入日志。参与者向协调者返回「投票结果」:同意提交(Yes)或拒绝提交(No)。
阶段二:提交(Commit)
若所有参与者返回 Yes:协调者向所有参与者发送 Commit 指令,事务提交成功。若有任意参与者返回 No:协调者发送 Rollback 指令,所有参与者回滚事务。
三、2PC 的问题
虽然简单,但 2PC 有以下缺陷:
阻塞问题
如果协调者宕机,参与者会一直阻塞,无法继续事务。
单点问题
协调者是单点故障,影响整个事务。
数据不一致
在第二阶段,若部分参与者收到 Commit,部分没收到(网络分区),会导致数据不一致。
👉 2PC 只能保证 原子性(Atomicity),但在高并发、网络故障场景下并不可靠。
四、3PC 协议(Three-Phase Commit)
为解决 2PC 的阻塞问题,提出了 3PC。
3PC 在 2PC 基础上增加了一个阶段(Pre-Commit),流程如下:
阶段一:CanCommit
协调者询问所有参与者是否可以执行事务。参与者检查资源是否可用,返回 Yes/No。
阶段二:PreCommit
如果所有参与者返回 Yes,协调者发送 PreCommit 指令。参与者执行事务操作,并进入「预提交」状态,但仍未提交。如果有参与者返回 No,则协调者直接发送 Abort 指令。
阶段三:DoCommit
如果协调者收到所有参与者的确认,则发送 DoCommit 指令,参与者提交事务。若超时未收到确认,参与者会自动提交或回滚,避免永久阻塞。
五、2PC vs 3PC 对比
特性2PC3PC提交阶段2 阶段3 阶段阻塞性强阻塞弱阻塞单点故障有(协调者)缓解(超时机制)一致性较弱较强,但仍可能出错工程实现简单,广泛使用复杂,理论价值更高
六、工程应用与改进
分布式数据库事务
MySQL XA、Oracle 等都实现了 2PC 协议。
消息队列 + 本地事务
RocketMQ 等采用「消息事务」方案,结合补偿机制。
补偿事务(TCC 模型)
Try-Confirm-Cancel,适用于业务层控制,避免阻塞。
结合一致性协议(Raft / Paxos)
实际工程中,常用 Raft/ZAB 来保证协调者的高可用,从而避免单点问题。
七、总结
2PC:简单直观,但有阻塞和单点问题。3PC:增加 PreCommit 阶段,缓解阻塞问题,但复杂度更高,工程实践少。现代分布式系统:大多采用「2PC + 补偿机制」或基于 Raft/ZAB 的强一致存储 来实现分布式事务。