202524 | 分布式事务

发布于:2025-04-13 ⋅ 阅读:(24) ⋅ 点赞:(0)

分布式事务(Distributed Transaction)

分布式事务是指跨多个数据库、服务或系统节点的事务操作,要求所有参与方要么全部成功提交,要么全部回滚,保证数据一致性。


1. 为什么需要分布式事务?

在单体应用中,事务可以通过数据库的 ACID(原子性、一致性、隔离性、持久性)保证。但在微服务或分布式系统中:

  • 数据分散:不同服务使用不同的数据库(如订单库、库存库、支付库)。
  • 网络不可靠:跨服务调用可能失败(如支付成功但库存扣减失败)。
  • 业务复杂:多个服务需要协同完成一个业务(如电商下单 → 支付 → 库存扣减)。

示例场景

用户下单
订单服务
支付服务
库存服务
  • 问题:如果支付成功但库存扣减失败,数据不一致!

2. 分布式事务的挑战(CAP理论)

在分布式系统中,无法同时满足:

  • 一致性(Consistency):所有节点数据一致。
  • 可用性(Availability):服务总能响应。
  • 分区容错性(Partition Tolerance):网络分区时仍能运行。

分布式系统必须选择 CP(强一致性)或 AP(高可用性)


分布式事务的解决方案

分布式事务解决方案终极详解

一、核心问题与挑战

在分布式系统中,事务需要跨多个服务或数据库,面临三大核心问题:

  1. 原子性破坏:部分操作成功,部分失败
  2. 数据不一致:网络延迟或故障导致状态不一致
  3. 性能瓶颈:同步阻塞降低系统吞吐量
分布式事务问题
原子性
一致性
性能
部分提交问题
中间状态可见
同步等待
二、强一致性方案详解
1. 2PC(两阶段提交)

核心思想:通过协调者统一调度

协调者 参与者1 参与者2 准备请求(PREPARE) 准备请求(PREPARE) 投票结果(YES/NO) 投票结果(YES/NO) 提交命令(COMMIT) 提交命令(COMMIT) 回滚命令(ROLLBACK) 回滚命令(ROLLBACK) alt [全票通过] [任意拒绝] 协调者 参与者1 参与者2

关键问题

  • 同步阻塞:所有参与者在准备阶段锁定资源
  • 单点故障:协调者宕机导致系统僵死
  • 数据不一致:网络分区时可能部分提交

优化方案

2PC缺陷
协调者集群
超时机制
日志持久化

2. Seata AT模式

架构原理

注册分支事务
生成逆向SQL
Transaction Coordinator
Resource Manager 1
Resource Manager 2

执行流程

  1. 一阶段
    • 解析业务SQL生成前后镜像
    • 本地提交并上报TC
  2. 二阶段
    • 成功:异步删除快照
    • 失败:用前镜像回滚

全局锁机制

获取锁
等待锁
事务1
数据行
事务2

三、最终一致性方案详解
1. TCC模式

三阶段操作

库存服务
订单服务
资源预留
预留取消
实际扣减
释放预留
确认订单
Confirm
取消订单
Cancel
Try

异常处理设计

应用 事务管理器 订单服务 库存服务 开始全局事务 Try 预留成功 Try 预留失败 Cancel Cancel 应用 事务管理器 订单服务 库存服务

注意事项

  • 必须实现幂等性
  • 需要空回滚和防悬挂处理
  • 业务侵入性强

2. Saga模式

两种实现方式对比

55% 45% Saga实现方式 事件编排 命令编排

事件编排示例

成功
失败
失败
订单创建
支付扣款
库存扣减
支付退款
库存补偿

补偿机制设计

正向操作
记录补偿日志
失败时读取日志
执行补偿操作

3. 本地消息表

完整架构

业务操作
写事务表
事务日志
定时任务
消息队列
消费者
业务处理
更新状态

可靠性保障

Producer 数据库 消息队列 Consumer 业务数据+消息(同事务) 发送未处理消息 loop [定时扫描] 消费消息 确认处理完成 Producer 数据库 消息队列 Consumer

四、方案选型矩阵**
维度 2PC TCC Saga 本地消息表 Seata AT
一致性 强一致 最终一致 最终一致 最终一致 强一致
性能 中高
侵入性
复杂度
适用场景 金融支付 电商秒杀 长事务 日志同步 微服务
选型决策
强一致性要求?
2PC/Seata AT
高并发需求?
TCC
Saga/消息表

Seata

一、Seata 核心架构
注册/上报
分支事务管理
分支事务管理
发起全局事务
本地事务执行
本地事务执行
Transaction Coordinator
Transaction Manager
Resource Manager 1
Resource Manager 2
应用程序
数据库1
数据库2

核心组件

  1. TC (Transaction Coordinator)
    • 事务协调器(独立部署)
    • 维护全局事务状态,驱动分支事务提交/回滚
  2. TM (Transaction Manager)
    • 集成在应用中
    • 定义事务边界,发起全局提交/回滚
  3. RM (Resource Manager)
    • 管理分支事务,向TC注册分支状态
    • 生成SQL镜像,实现数据回滚

二、Seata 的四种模式对比
模式 一致性 性能 侵入性 适用场景
AT 强一致 常规微服务
TCC 最终 极高 高并发(如秒杀)
Saga 最终 长事务流程
XA 强一致 传统数据库兼容

三、AT 模式详解(默认模式)

image-20250405082012305

1. 执行流程
应用 TM TC RM 数据库 @GlobalTransactional 开启全局事务(XID) 返回XID 执行SQL 更新数据 注册分支事务 生成undo_log(前后镜像) loop [业务逻辑] 全局提交 异步删除undo_log 全局回滚 根据undo_log回滚 alt [全部成功] [任意失败] 应用 TM TC RM 数据库
2. 核心机制
  • 全局锁:防止脏写
    获取行锁
    阻塞等待
    事务1
    数据行
    事务2
  • undo_log表
    CREATE TABLE `undo_log` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `branch_id` bigint(20) NOT NULL,
      `xid` varchar(100) NOT NULL,
      `context` varchar(128) NOT NULL,
      `rollback_info` longblob NOT NULL,
      `log_status` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    );
    
3. 适用场景
  • 80%的常规分布式事务场景
  • 支持MySQL、Oracle等主流数据库

四、TCC 模式详解
1. 三阶段操作
库存服务
订单服务
预留资源
取消预留
实际扣减库存
释放冻结库存
订单状态:已支付
Confirm
订单状态:已取消
Cancel
Try
2. 异常处理设计
应用 TM 订单服务 库存服务 开始TCC事务 Try(冻结订单) 成功 Try(冻结库存) 失败 Cancel(解冻订单) Cancel(解冻库存) 应用 TM 订单服务 库存服务
3. 注意事项
  • 必须实现幂等性
  • 需要处理空回滚和防悬挂
  • 典型业务代码:
    @LocalTCC
    public interface OrderTccService {
        @TwoPhaseBusinessAction(name = "createOrder", commitMethod = "confirm", rollbackMethod = "cancel")
        boolean tryCreateOrder(Order order);
        
        boolean confirm(Order order);
        
        boolean cancel(Order order);
    }
    

五、Saga 模式详解
1. 状态机设计
成功
失败
成功
失败
订单创建
支付中
已支付
支付失败
库存扣减
已发货
库存不足
退款处理
订单关闭
2. 补偿机制
正向操作
记录执行日志
失败时触发补偿
读取日志逆向操作
3. 适用场景
  • 跨多服务的业务流程(如电商下单→支付→物流)
  • 每个步骤都需要显式定义补偿操作

六、XA 模式详解
1. 传统XA协议增强
应用 TC RM 数据库 开启XA事务 注册分支 XA START 执行SQL XA END XA PREPARE XA COMMIT XA ROLLBACK alt [全部成功] [任意失败] 应用 TC RM 数据库
2. 特点
  • 完全兼容传统XA协议
  • 需要数据库支持XA(MySQL 5.7+)

七、Seata 生产实践
1. 部署架构
应用1
TC集群
应用2
注册中心
配置中心
存储模式
2. 高可用配置
# registry.conf
registry {
  type = "nacos"
  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    cluster = "default"
  }
}

store {
  mode = "db"
  db {
    datasource = "druid"
    url = "jdbc:mysql://127.0.0.1:3306/seata"
    user = "root"
    password = "123456"
  }
}
3. 性能调优
# 调整TC处理线程数
server.max.commit.retry.timeout=60000
server.max.rollback.retry.timeout=60000
store.db.global.table=global_table
store.db.branch.table=branch_table

八、Seata 与同类方案对比
特性 Seata DTX ShardingSphere
AT模式 ✔️ ✖️ ✖️
TCC支持 ✔️ ✔️ ✖️
Saga支持 ✔️ ✖️ ✔️
XA支持 ✔️ ✔️ ✔️
无侵入 AT/XA ✖️ ✖️

九、最佳实践建议
  1. 常规业务:优先使用AT模式
  2. 高并发场景:TCC + 异步Confirm
  3. 长业务流程:Saga状态机 + 可视化监控
  4. 传统系统改造:XA模式

如果需要 具体场景的完整代码示例(如电商下单的AT模式实现),可以告诉我具体需求!


网站公告

今日签到

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