Java-58 深入浅出 分布式服务 ACID 三阶段提交3PC 对比2PC

发布于:2025-06-29 ⋅ 阅读:(19) ⋅ 点赞:(0)

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

目前2025年06月16日更新到:
AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年06月26日更新到:
Java-55 深入浅出 分布式服务 分布式一致性 强一致、弱一致、单调读一致、最终一致
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
目前2025年06月13日更新到:
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

请添加图片描述

一致性3PC(Three-Phase Commit)

概述

3PC(Three-Phase Commit)全称为三阶段提交协议,是二阶段提交协议(2PC)的改进版本。3PC将2PC的提交事务请求过程进一步细分为两个阶段,最终形成由CanCommit、PreCommit和doCommit三个阶段组成的分布式事务处理协议。

协议阶段详解

1. CanCommit阶段(询问阶段)

  • 协调者向所有参与者发送CanCommit请求
  • 参与者检查自身状态,判断是否可以执行事务
  • 参与者回复Yes/No响应(ACK/NACK)
  • 协调者根据响应决定是否进入下一阶段

2. PreCommit阶段(准备阶段)

  • 若全部参与者回复Yes,协调者发送PreCommit请求
  • 参与者执行事务操作但不提交,写入undo/redo日志
  • 参与者锁定相关资源,确保事务可回滚
  • 参与者回复Ack确认准备完成

3. doCommit阶段(提交阶段)

  • 协调者收到所有Ack后发送doCommit请求
  • 参与者正式提交事务
  • 参与者释放资源锁
  • 参与者回复Ack确认提交完成

改进优势

与2PC相比,3PC的主要改进包括:

  1. 增加了CanCommit阶段,提前验证参与者状态
  2. 降低了阻塞风险(引入超时机制)
  3. 提高了系统可用性(部分故障可继续运行)
  4. 减少了协调者单点故障的影响

应用场景

3PC适用于以下分布式系统场景:

  • 数据库集群事务处理
  • 跨服务的事务协调
  • 微服务架构中的Saga模式
  • 需要较高可用性的分布式系统

局限性

尽管3PC有所改进,但仍存在以下问题:

  • 网络分区时可能导致数据不一致
  • 实现复杂度高于2PC
  • 性能开销相对较大
  • 不能完全解决所有分布式一致性问题

在这里插入图片描述

阶段一

● 事务询问:协调者向所有参与者发送一个包含事务内容的canCommit请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应
● 各参与者向协调者反馈事务询问的响应:参与者在接收到来自协调者的包含了事务内容的canCommit请求后,在正常情况下,如果自身认为可以顺利执行事务,则反馈Yes,并进入预备状态,否则反馈No响应。

在这里插入图片描述

阶段二

PreCommit
协调者在得到参与者的响应之后,会根据结果有2种执行操作的情况:执行事务预提交,或者中断事务。
假如所有参与者反馈的都是Yes,那么就会执行事务预提交。

● 发送预提交请求:协调者向所有参与节点发出 preCommit 请求,并进入 prepared 阶段
● 事务预提交:参与者接收到 preCommit 请求后,会执行事务操作,并将 Undo、Redo 信息记录到事务日志中
● 各参与协调者反馈事务执行的结果:若参与者执行成功了事务操作,那么反馈ACK。若任一参与者反馈了No的时候,或者超时之后,协调者无法收到所有参与者的响应,则中断事务

中断事务也分为两个步骤:
● 发送中断请求:协调者向所有参与者发出 abort 请求
● 中断事务:无论是收到来自协调者的abort请求或者等待协调者请求过程中超时,参与者都会中断事务

在这里插入图片描述

阶段三

doCommit

该阶段做真正的事务提交或者完成事务回滚,所有会出现两种情况:

情况一 执行事务提交

● 发送提交请求:进入这一阶段,假设协调者处于正常工作状态,并且它接收到了来自所有参与者ACK响应,那么他将从预提交状态转换为提交状态,并向所有参与者发送doCommit请求
● 事务提交:参与者收到doCommit请求后,会正式执行事务提交操作,并在完成提交之后释放整个事务执行过程中占用的事务资源。
● 反馈事务提交结果:参与者在完成事务提交后,向协调者发送ACK响应
● 完成事务:协调者接收到所有参与者反馈的ACK消息之后,完成事务。

情况二 中断事务

● 发送中断请求:协调者向所有的参与者节点发送abort请求。
● 事务回滚:参与者收到abort请求后,会根据记录的Undo信息来执行事务回滚,并在完成回滚之后释放整个事务执行期间占用的资源
● 反馈事务回滚结果:参与者在完成事务回滚后,向协调者发送ACK消息
● 中断事务:协调者接收到所有参与者反馈的ACK消息后,中断事务

注意:一旦进入阶段三,可能会出现2种故障:
● 协调者出现问题
● 协调者和参与者之间的网络故障

如果出现任意一种情况,最终都会导致参与者无法收到 doCommit 请求 或者 abort 请求,针对这种情况,参与者都会在超时之后,继续进行事务提交

2PC对比3PC

超时机制改进

在2PC(两阶段提交)协议中,只有协调者拥有超时机制。这意味着当协调者在规定时间内没有收到参与者的响应时,会默认事务执行失败。然而,3PC(三阶段提交)对此进行了重要改进:

  1. 参与者超时机制:
    • 每个参与者都设置了超时计时器
    • 如果在CanCommit或PreCommit阶段长时间未收到协调者指令(如网络分区或协调者故障)
    • 参与者会在超时后自动执行本地Commit操作释放资源

实际应用场景示例:
当电商系统处理分布式订单时,如果支付服务(参与者)在PreCommit阶段与订单服务(协调者)失去连接,支付服务会在超时后自动提交本地事务,避免资金长时间冻结。

三阶段设计优势

3PC通过三个阶段的设计提供了更好的可靠性:

  1. CanCommit阶段:

    • 协调者询问参与者是否具备执行事务的条件
    • 参与者检查资源可用性但不锁定资源
    • 类似于"预检查"阶段
  2. PreCommit阶段:

    • 核心缓冲阶段
    • 协调者在收到所有参与者的Yes响应后发送PreCommit请求
    • 参与者执行事务操作但暂不提交
    • 在此阶段确保所有参与者状态一致
  3. DoCommit阶段:

    • 最终提交阶段
    • 协调者确认所有参与者完成PreCommit后发送提交指令

分阶段好处示例:
在银行转账系统中,PreCommit阶段可以确保所有账户的余额检查通过且金额已临时扣减,才会进入最终提交阶段,避免部分账户扣款成功而其他账户失败的情况。

局限性

尽管有上述改进,3PC仍存在以下问题:

  1. 数据不一致的可能性:

    • 在DoCommit阶段若发生网络分区
    • 部分参与者可能收不到提交指令
    • 导致系统部分节点已提交而其他节点未提交
  2. 性能损耗:

    • 额外的通信阶段增加了延迟
    • 不适合对延迟敏感的应用场景
  3. 实现复杂度:

    • 需要更复杂的状态机来处理各阶段异常
    • 增加了系统开发和维护成本

实际案例:
在分布式数据库系统中,即使使用3PC,仍然需要额外的补偿机制(如人工干预或自动修复程序)来处理极端情况下出现的数据不一致问题。


网站公告

今日签到

点亮在社区的每一天
去签到