两阶段提交(2PC)

两阶段提交先由协调者询问所有参与者能否提交(准备阶段),全部同意后再统一提交;任一阶段失败或协调者宕机都可能造成资源长期锁定。

2PC 是什么

两阶段提交用协调者统一推动多个参与者的事务:第一阶段协调者询问各参与者能否提交,参与者执行操作、锁定资源并回复是否可以;第二阶段全部同意则统一提交,任一不同意则统一回滚。它保证跨库操作的原子性,但属于阻塞式协议:参与者回复同意后若协调者宕机,资源会一直锁定直到协调者恢复并给出最终决策。

基本信息

阶段一协调者询问,参与者锁定资源并回复是否可以提交
阶段二全部同意则提交,否则全部回滚
主要问题阻塞式协议,参与者在不确定状态下可能长期等待
单点风险协调者是关键单点,宕机会造成资源锁定
常见实现数据库的 XA 事务、部分消息中间件的事务消息

阶段与故障点

阶段与故障点
阶段一:协调者 → 参与者:能否提交?
        参与者锁定资源,执行操作,回复 同意/拒绝
阶段二:全部同意 → 提交;否则 → 回滚

故障点:参与者回复同意后协调者宕机
        → 参与者保持锁定,等待恢复后的最终决策
注意:超时不能等同于回滚,参与者无法单方面决定

跨服务替代方案

方案一致性适用场景
本地消息表最终一致同一服务内业务与消息写入同库
Saga 补偿最终一致步骤可定义补偿的跨服务流程
事务消息最终一致基于消息中间件提供的事务能力
对账与补偿最终一致允许延迟对齐的账务与统计场景

典型使用场景

  • 同一数据库多数据源操作:XA 事务保证整体原子性
  • 消息发送与业务写入:用事务消息避免消息与业务不一致
  • 金融批量处理:要求批次内全部成功或全部失败的场景
  • 跨系统对接评估:判断是否值得引入 2PC 或改用最终一致
  • 故障演练设计:验证协调者宕机时的资源锁定与恢复路径
  • 容量评估:评估锁定时间对连接池与并发能力的挤压
2PC 保证的是原子性而不是性能:锁定窗口通常比本地事务长得多,在高并发下会显著降低吞吐,因此更适合低频且关键的批量场景。
把 2PC 用于跨组织的服务调用,协调者无法控制对端超时与故障语义,参与者长时间持锁的风险显著上升。

易错点

  • 协调者宕机后参与者长期持锁,影响面沿数据库连接池迅速扩散
  • 把 2PC 用于跨组织调用,协调者不可控且超时语义不一致
  • 把参与者的超时当作回滚处理,实际状态 Unknown,产生数据分叉
  • 高并发写入路径上使用 2PC,锁等待导致接口大面积超时
  • 缺少事务日志与恢复流程,协调者重启后无法判断应提交还是回滚

数据来源与参考

  • Bernstein, Hadzilacos & Goodman《Concurrency Control and Recovery in Database Systems》(1987)
  • 《数据密集型应用系统设计》(Kleppmann)第 9 章
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌