一、什么是2PC?—— 分布式世界的“交通灯”
2PC(Two-Phase Commit) 是分布式系统中保证原子性的核心协议,就像交通信号灯协调多辆车同时通过路口。其核心目标是:让多个服务在同一个事务中,要么全部成功,要么全部失败。
核心角色:
• 协调者(Coordinator):指挥官,负责统筹全局事务(如订单系统)。
• 参与者(Participant):士兵,执行具体业务操作的服务(如库存系统、支付系统)。
通俗比喻:
想象你和朋友约好一起做饭,你负责买菜(参与者A),朋友负责炒菜(参与者B)。协调者就是你们的“总指挥”,确保两人要么都完成,要么都不做。
二、2PC原理:两步走战略
1. 第一阶段:准备阶段(Prepare Phase)
• 协调者发令:
“所有人准备好!我要检查你们的任务是否能完成。”
• 参与者响应:
• 执行本地操作(如扣减库存、冻结支付金额),记录** undo 日志**(回滚脚本)。
• 回答“是”(Yes)或“否”(No):
◦ Yes:表示“我能完成,但还没提交”。
◦ No:表示“我做不到”(如库存不足)。
关键点:
• 参与者不提交事务,只“预提交”。
• 通过**事务ID(XID)**唯一标识全局事务。
2. 第二阶段:提交阶段(Commit Phase)
• 协调者根据反馈决策:
• 所有参与者都说“Yes” → 发送“全体提交!”命令。
• 至少一个说“No” → 发送“全体回滚!”命令。
• 参与者执行最终操作:
• 提交:正式提交本地事务,释放资源。
• 回滚:根据undo日志恢复数据(如库存加回来)。
流程图解:
协调者 → [Prepare] → 参与者A
协调者 → [Prepare] → 参与者B
...
← [Yes/No] ← 参与者B
← [Yes/No] ← 参与者A
协调者 → [Commit/Rollback] → 所有参与者
三、2PC适用场景:强一致性的刚需
以下场景必须用2PC(或类似协议):
- 金融转账:
• 用户A扣款100元,用户B加款100元。
• 必须保证两者原子性,否则会资损。 - 电商订单:
• 扣减库存 → 生成订单 → 扣款 → 发送物流。
• 任一环节失败,需全部回滚。 - 分布式数据库:
• 跨库事务(如MySQL + PostgreSQL)。
反例:
• 日志记录:允许异步写入,最终一致即可。
• 统计报表:数据允许稍晚更新。
四、实战:手把手实现2PC
4.1 最简代码示例
// 协调者类
public class Coordinator {
private List<Participant> participants = new ArrayList<>();
public void addParticipant(Participant p) {
participants.add(p);
}
// 第一阶段:准备
public boolean prepare() {
boolean allReady = true;
for (Participant p : participants

最低0.47元/天 解锁文章
814

被折叠的 条评论
为什么被折叠?



