分布式事务

Posted by pigTom on January 14, 2026

分布式事务指南

最后更新:2026-01-15

目录

  1. 什么是分布式事务
  2. 分布式事务要解决的问题
  3. 理论基础
  4. 分布式事务的类型与原理
  5. 分布式事务的发展历程
  6. 重要论文与理论
  7. 应用场景
  8. 主流解决方案对比
  9. 学习资源
  10. 常见问题解答

什么是分布式事务

定义

分布式事务是指在分布式系统中,涉及多个节点、多个服务或多个数据库的操作需要作为一个整体事务来保证其一致性完整性的机制。

通俗理解

想象你在电商平台购物:

  • 订单服务需要创建订单
  • 库存服务需要扣减库存
  • 支付服务需要处理支付
  • 积分服务需要增加积分

这些服务可能部署在不同的服务器上,使用不同的数据库。如何保证这些操作要么全部成功,要么全部失败?这就是分布式事务要解决的核心问题。

与单机事务的区别

特性 单机事务 分布式事务
数据位置 单一数据库 多个数据库/服务
事务管理 本地事务管理器 全局事务协调器
一致性保证 ACID 强一致性 通常是最终一致性
性能影响 较小 较大(网络通信)
实现复杂度
故障场景 相对简单 复杂(网络分区、节点故障等)

分布式事务要解决的问题

核心挑战

1. 数据一致性问题

在分布式系统中,如何保证多个节点的数据在事务执行前后保持一致?

问题场景

  • 订单已创建,但库存扣减失败
  • 支付成功,但订单状态更新失败
  • 部分服务提交成功,部分服务回滚

2. 网络不可靠问题

网络通信可能出现的问题:

  • 延迟:消息传递存在延迟
  • 丢失:消息可能丢失
  • 重复:消息可能重复发送
  • 乱序:消息到达顺序可能错乱
  • 分区:网络分区导致节点间无法通信

3. 节点故障问题

  • 协调者节点故障
  • 参与者节点故障
  • 部分节点故障(部分成功、部分失败)

4. 性能与可用性权衡

  • 强一致性会降低系统可用性
  • 分布式锁会降低系统性能
  • 事务协调增加响应延迟

理论基础

CAP 定理

提出者:Eric Brewer(2000年)

核心内容:在分布式系统中,以下三个特性无法同时完全满足,最多只能同时满足其中两项:

C - Consistency(一致性)

所有节点在同一时间看到的数据是一致的。

示例:用户在节点 A 写入数据后,立即从节点 B 读取,能读到最新数据。

A - Availability(可用性)

系统在任何时候都能响应用户的请求(非错误响应)。

示例:即使部分节点故障,系统仍然能够处理请求。

P - Partition Tolerance(分区容错性)

系统能够容忍网络分区故障,即使节点间无法通信,系统仍能继续运行。

示例:网络故障导致集群分裂为两部分,系统仍能继续提供服务。

CAP 权衡

        一致性 (C)
           /\
          /  \
         /    \
        /  CA  \
       /        \
      /----------\
     /   /\  /\   \
    /   /  \/  \   \
   /   / CP  AP \   \
  /   /          \   \
 /   /____________\   \
可用性(A)          分区容错性(P)

在实际应用中:

  • CA:单机数据库(MySQL、PostgreSQL)
  • CP:分布式协调系统(Zookeeper、etcd、HBase)
  • AP:最终一致性系统(Cassandra、DynamoDB)

注意:分区容错性(P)在分布式系统中通常是必须的,因此实际上是在 C 和 A 之间权衡。

BASE 理论

BASE 理论是对 CAP 定理中一致性和可用性权衡的结果,是 Basically AvailableSoft StateEventually Consistent 的缩写。

BA - Basically Available(基本可用)

系统在出现故障时,允许损失部分可用性,但保证核心功能可用。

具体表现

  • 响应时间略有增加
  • 部分非核心功能降级
  • 限流、熔断保护核心服务

S - Soft State(软状态)

允许系统中的数据存在中间状态,并认为该中间状态不会影响系统整体可用性。

具体表现

  • 数据副本之间的同步允许延迟
  • 订单状态可能经历”待确认” → “处理中” → “已完成”
  • 临时状态的存在不影响最终结果

E - Eventually Consistent(最终一致性)

系统中所有的数据副本,在经过一段时间的同步后,最终能达到一致的状态。

具体表现

  • 不保证实时一致性
  • 在一定时间窗口后达到一致
  • 适用于对实时性要求不高的场景

ACID vs BASE

特性 ACID BASE
目标 强一致性 高可用性
一致性 强一致性 最终一致性
事务模型 刚性事务 柔性事务
性能 较低 较高
复杂度 相对简单 相对复杂
适用场景 金融、支付核心业务 互联网高并发场景
典型代表 传统关系型数据库 NoSQL、微服务

分布式事务的类型与原理

1. 两阶段提交(2PC - Two-Phase Commit)

原理

2PC 是最经典的分布式事务协议,将事务处理分为两个阶段:

阶段一:准备阶段(Prepare Phase / Vote Phase)

协调者 (Coordinator)
    |
    |-- PREPARE --> 参与者1 (Participant 1)
    |                  |
    |                  v
    |             [执行事务但不提交]
    |                  |
    |                  v
    |             [写入 undo/redo 日志]
    |                  |
    |                  v
    |            YES/NO (投票)
    |
    |-- PREPARE --> 参与者2 (Participant 2)
    |                  |
    |                  v
    |            YES/NO (投票)
    |
    v
 [收集所有投票]

流程

  1. 协调者向所有参与者发送 PREPARE 请求
  2. 参与者执行事务操作,但不提交
  3. 参与者记录 undo/redo 日志
  4. 参与者锁定相关资源
  5. 参与者返回 YES(准备就绪)或 NO(失败)

阶段二:提交阶段(Commit Phase)

协调者
    |
    v
 [所有参与者都返回 YES?]
    |
    |-- YES --> 发送 COMMIT 给所有参与者
    |              |
    |              v
    |          [提交事务]
    |              |
    |              v
    |          [释放资源]
    |              |
    |              v
    |          [返回 ACK]
    |
    |-- NO --> 发送 ROLLBACK 给所有参与者
                   |
                   v
               [回滚事务]
                   |
                   v
               [释放资源]
                   |
                   v
               [返回 ACK]

流程

  • 如果所有参与者都返回 YES
    1. 协调者发送 COMMIT 指令
    2. 参与者提交事务
    3. 参与者释放资源
    4. 参与者返回 ACK
  • 如果任何参与者返回 NO
    1. 协调者发送 ROLLBACK 指令
    2. 参与者回滚事务
    3. 参与者释放资源
    4. 参与者返回 ACK

优点

  • ✅ 强一致性保证
  • ✅ 实现相对简单
  • ✅ 原理清晰易懂

缺点

  • 同步阻塞:参与者在等待协调者指令期间,资源被锁定
  • 单点故障:协调者故障会导致所有参与者阻塞
  • 数据不一致风险:在提交阶段,如果部分参与者收到 COMMIT,部分未收到(网络问题),会导致数据不一致
  • 性能较差:需要多次网络通信,且存在阻塞

故障场景分析

场景1:协调者在准备阶段故障

  • 影响:所有参与者等待超时
  • 解决:参与者超时后自动回滚

场景2:协调者在提交阶段故障

  • 影响:参与者不知道是提交还是回滚
  • 解决:参与者无法自行决定,只能等待协调者恢复(阻塞)

场景3:参与者在准备阶段故障

  • 影响:协调者收不到该参与者的投票
  • 解决:协调者决定回滚事务

场景4:网络分区导致部分参与者未收到提交指令

  • 影响:部分提交,部分未提交,数据不一致
  • 解决:需要人工介入或更复杂的恢复机制

2. 三阶段提交(3PC - Three-Phase Commit)

设计目标

为了解决 2PC 的阻塞问题和单点故障问题,3PC 引入了超时机制CanCommit 阶段

原理

阶段一:CanCommit 阶段(询问阶段)

协调者
    |
    |-- CanCommit? --> 参与者1
    |                     |
    |                     v
    |                 [检查资源]
    |                     |
    |                     v
    |                  YES/NO
    |
    |-- CanCommit? --> 参与者2
                          |
                          v
                       YES/NO

流程

  1. 协调者向参与者发送 CanCommit 请求
  2. 参与者判断是否可以执行事务(不执行具体操作)
  3. 参与者返回 YES 或 NO

阶段二:PreCommit 阶段(预提交阶段)

协调者
    |
    v
 [所有参与者返回 YES?]
    |
    |-- YES --> 发送 PreCommit 给所有参与者
    |              |
    |              v
    |          [执行事务但不提交]
    |              |
    |              v
    |          [写入 undo/redo 日志]
    |              |
    |              v
    |          [返回 ACK]
    |
    |-- NO --> 发送 Abort 给所有参与者
                   |
                   v
               [中止事务]

流程

  • 如果所有参与者返回 YES
    1. 协调者发送 PreCommit 请求
    2. 参与者执行事务操作(但不提交)
    3. 参与者返回 ACK
  • 如果任何参与者返回 NO
    1. 协调者发送 Abort 请求
    2. 参与者中止事务

阶段三:DoCommit 阶段(提交阶段)

协调者
    |
    v
 [所有参与者返回 ACK?]
    |
    |-- YES --> 发送 DoCommit 给所有参与者
    |              |
    |              v
    |          [提交事务]
    |              |
    |              v
    |          [返回 ACK]
    |
    |-- NO/TIMEOUT --> 发送 Abort 给所有参与者
                          |
                          v
                      [回滚事务]

关键改进:超时机制

  • 参与者在 PreCommit 后,如果等待超时仍未收到 DoCommit,自动提交事务
  • 这是基于”已经进入 PreCommit 阶段,大概率会提交”的假设

优点

  • ✅ 降低阻塞时间(引入超时机制)
  • ✅ 降低单点故障影响
  • ✅ 参与者可以在超时后自行决策

缺点

  • ❌ 实现更加复杂
  • ❌ 增加了一次网络通信
  • ❌ 在极端情况下仍可能数据不一致(网络分区)
  • ❌ 超时自动提交的假设可能不成立

3PC vs 2PC

特性 2PC 3PC
阶段数 2 个阶段 3 个阶段
超时机制
阻塞时间 较长 较短
单点故障影响 严重 较小
实现复杂度
网络通信次数 较少 较多
性能 较差 更差
一致性保证 强一致 强一致(理论上)

3. XA 协议

定义

XA 协议是由 X/Open 组织提出的分布式事务规范,定义了事务管理器(TM)与资源管理器(RM)之间的接口。

核心组件

应用程序 (Application)
        |
        v
事务管理器 (TM - Transaction Manager)
        |
        |-- XA 接口
        |
        v
资源管理器 (RM - Resource Manager)
   |         |         |
   v         v         v
 数据库1   数据库2   消息队列

角色

  • AP (Application Program):应用程序,定义事务边界
  • TM (Transaction Manager):事务管理器,协调全局事务
  • RM (Resource Manager):资源管理器,管理共享资源(如数据库)

XA 接口方法

xa_start    // 开始事务分支
xa_end      // 结束事务分支
xa_prepare  // 准备提交
xa_commit   // 提交事务
xa_rollback // 回滚事务
xa_recover  // 恢复未完成的事务

工作流程

XA 协议基于 2PC 实现:

1. 应用程序调用 TM 开启全局事务
2. TM 为每个 RM 分配事务分支 ID
3. 应用程序通过 TM 操作各个 RM
4. TM 向所有 RM 发送 xa_prepare
5. 所有 RM 返回成功后,TM 发送 xa_commit
6. 如有 RM 失败,TM 发送 xa_rollback

数据库支持

  • MySQL:支持 XA(InnoDB 引擎)
  • PostgreSQL:支持 XA
  • Oracle:支持 XA
  • SQL Server:支持分布式事务(MS DTC)

MySQL XA 示例

-- 会话1:参与者1
XA START 'xid1';
UPDATE account SET balance = balance - 100 WHERE id = 1;
XA END 'xid1';
XA PREPARE 'xid1';
-- 等待协调者指令
XA COMMIT 'xid1';  -- 或 XA ROLLBACK 'xid1';

-- 会话2:参与者2
XA START 'xid2';
UPDATE account SET balance = balance + 100 WHERE id = 2;
XA END 'xid2';
XA PREPARE 'xid2';
-- 等待协调者指令
XA COMMIT 'xid2';  -- 或 XA ROLLBACK 'xid2';

优点

  • ✅ 标准化接口
  • ✅ 数据库原生支持
  • ✅ 强一致性保证

缺点

  • ❌ 性能开销大
  • ❌ 长时间锁定资源
  • ❌ 不适合高并发场景
  • ❌ 依赖数据库实现(跨异构系统困难)

4. TCC(Try-Confirm-Cancel)

定义

TCC 是一种侵入式的分布式事务解决方案,将业务操作拆分为三个阶段:Try、Confirm、Cancel。

三个阶段

Try 阶段(尝试)

  • 完成所有业务检查(一致性)
  • 预留必须的业务资源(准隔离性)
  • 不提交事务

Confirm 阶段(确认)

  • 真正执行业务操作
  • 不做任何业务检查
  • 只使用 Try 阶段预留的资源
  • Confirm 操作必须保证幂等性

Cancel 阶段(取消)

  • 释放 Try 阶段预留的资源
  • Cancel 操作必须保证幂等性

工作流程

                 TCC 协调器
                      |
      +---------------+---------------+
      |               |               |
      v               v               v
   服务A           服务B           服务C
      |               |               |
 [Try 阶段]      [Try 阶段]      [Try 阶段]
      |               |               |
   成功              成功             成功
      |               |               |
      +---------------+---------------+
                      |
                      v
              [所有 Try 都成功?]
                      |
          +-----------+-----------+
          |                       |
        YES                      NO
          |                       |
          v                       v
   [Confirm 阶段]          [Cancel 阶段]
          |                       |
     确认所有服务             取消所有服务

实际案例:转账业务

场景:账户 A 向账户 B 转账 100 元

Try 阶段

// 账户 A:冻结 100 元
boolean tryDeduct(String accountId, BigDecimal amount) {
    // 1. 检查账户余额是否足够
    Account account = accountDao.findById(accountId);
    if (account.getBalance().compareTo(amount) < 0) {
        return false;
    }

    // 2. 冻结金额(不扣减余额,增加冻结金额)
    account.setFrozenAmount(account.getFrozenAmount().add(amount));
    accountDao.update(account);
    return true;
}

// 账户 B:预增加 100 元(记录待确认金额)
boolean tryAdd(String accountId, BigDecimal amount) {
    Account account = accountDao.findById(accountId);
    account.setPendingAmount(account.getPendingAmount().add(amount));
    accountDao.update(account);
    return true;
}

Confirm 阶段

// 账户 A:扣减余额,释放冻结金额
void confirmDeduct(String accountId, BigDecimal amount) {
    Account account = accountDao.findById(accountId);
    account.setBalance(account.getBalance().subtract(amount));
    account.setFrozenAmount(account.getFrozenAmount().subtract(amount));
    accountDao.update(account);
}

// 账户 B:增加余额,清除待确认金额
void confirmAdd(String accountId, BigDecimal amount) {
    Account account = accountDao.findById(accountId);
    account.setBalance(account.getBalance().add(amount));
    account.setPendingAmount(account.getPendingAmount().subtract(amount));
    accountDao.update(account);
}

Cancel 阶段

// 账户 A:释放冻结金额
void cancelDeduct(String accountId, BigDecimal amount) {
    Account account = accountDao.findById(accountId);
    account.setFrozenAmount(account.getFrozenAmount().subtract(amount));
    accountDao.update(account);
}

// 账户 B:清除待确认金额
void cancelAdd(String accountId, BigDecimal amount) {
    Account account = accountDao.findById(accountId);
    account.setPendingAmount(account.getPendingAmount().subtract(amount));
    accountDao.update(account);
}

关键点

1. 幂等性

Confirm 和 Cancel 操作必须支持幂等,因为可能会重试。

实现方式

  • 记录事务执行状态
  • 使用唯一事务 ID
  • 执行前检查是否已执行

2. 空回滚

Cancel 操作可能在 Try 操作还未执行时就被调用(网络延迟)。

解决方案

  • 记录事务状态
  • Cancel 时检查 Try 是否执行

3. 悬挂

Try 超时后执行了 Cancel,但 Try 请求最终还是到达了。

解决方案

  • Cancel 执行后标记该事务
  • Try 执行前检查是否已被 Cancel

优点

  • ✅ 不依赖数据库,可跨数据库、跨服务
  • ✅ 性能较好(不长时间锁资源)
  • ✅ 数据最终一致性有保证

缺点

  • ❌ 代码侵入性强(需要实现 Try、Confirm、Cancel 三个方法)
  • ❌ 开发成本高
  • ❌ 业务复杂度增加
  • ❌ 需要考虑幂等、空回滚、悬挂等问题

适用场景

  • 对性能要求较高
  • 业务可控性强
  • 需要跨数据库、跨服务的事务

5. Saga 模式

定义

Saga 模式是一种长事务解决方案,将全局事务拆分为一系列本地事务,每个本地事务都有对应的补偿操作

核心思想

T1 → T2 → T3 → T4 → ... → Tn

如果 Tn 失败,则执行:
Cn-1 → Cn-2 → ... → C2 → C1
  • Ti:正向操作(本地事务)
  • Ci:补偿操作(回滚逻辑)

两种实现方式

1. 事件驱动编排(Event Choreography)

各服务之间通过事件进行通信,无中央协调器。

服务A → [事件] → 服务B → [事件] → 服务C
  |                |                |
  v                v                v
执行T1            执行T2            执行T3
  |                |                |
  +--------失败-----+                |
           |                        |
           v                        |
       [发布补偿事件]                |
           |                        |
           v                        v
       执行C1                    执行C2

特点

  • 去中心化
  • 服务高度解耦
  • 实现复杂(需要设计事件流)

2. 命令协调(Command Orchestration)

使用中央协调器来管理 Saga 流程。

       Saga 协调器
            |
   +--------+--------+
   |        |        |
   v        v        v
 服务A    服务B    服务C
   |        |        |
  T1       T2       T3
   |        |        |
  成功     成功      失败
   |        |        |
   +--------+--------+
            |
            v
       [触发补偿]
            |
   +--------+--------+
   |        |
   v        v
  C2       C1

特点

  • 中心化管理
  • 流程清晰
  • 易于监控和维护

实际案例:订单处理

业务流程

  1. 创建订单
  2. 扣减库存
  3. 处理支付
  4. 发送通知

正向操作

T1: 创建订单(订单状态:待支付)
T2: 扣减库存
T3: 处理支付
T4: 发送通知(订单状态:已完成)

补偿操作

C1: 取消订单(订单状态:已取消)
C2: 恢复库存
C3: 退款处理
C4: 发送取消通知

执行流程示例

// Saga 协调器
public class OrderSaga {

    public void executeOrder(Order order) {
        try {
            // T1: 创建订单
            orderService.createOrder(order);

            try {
                // T2: 扣减库存
                inventoryService.deductInventory(order.getItems());

                try {
                    // T3: 处理支付
                    paymentService.processPayment(order.getPaymentInfo());

                    // T4: 发送通知
                    notificationService.sendNotification(order);

                } catch (Exception e) {
                    // C3: 退款(如果支付失败)
                    // 支付失败不需要退款
                    // C2: 恢复库存
                    inventoryService.restoreInventory(order.getItems());
                    // C1: 取消订单
                    orderService.cancelOrder(order.getId());
                    throw e;
                }

            } catch (Exception e) {
                // C2: 恢复库存(如果扣减库存失败)
                // 库存扣减失败不需要恢复
                // C1: 取消订单
                orderService.cancelOrder(order.getId());
                throw e;
            }

        } catch (Exception e) {
            // C1: 取消订单(如果创建订单失败)
            // 创建订单失败不需要取消
            throw e;
        }
    }
}

状态机实现

使用状态机管理 Saga 流程:

[开始]
  |
  v
[创建订单] ----失败----> [结束]
  |
 成功
  |
  v
[扣减库存] ----失败----> [取消订单] --> [结束]
  |
 成功
  |
  v
[处理支付] ----失败----> [恢复库存] --> [取消订单] --> [结束]
  |
 成功
  |
  v
[发送通知]
  |
  v
[结束]

关键点

1. 补偿操作设计

补偿操作不是简单的回滚,而是业务上的”反向操作”。

示例

  • 正向:扣减库存 → 补偿:增加库存
  • 正向:冻结资金 → 补偿:解冻资金
  • 正向:发货 → 补偿:召回商品(可能无法完全补偿)

2. 补偿的幂等性

补偿操作可能会被多次调用,必须保证幂等性。

3. 补偿的顺序

补偿操作通常按照正向操作的逆序执行。

4. 补偿失败处理

  • 重试机制
  • 人工介入
  • 记录日志

优点

  • ✅ 支持长事务
  • ✅ 不需要锁定资源
  • ✅ 吞吐量高
  • ✅ 实现相对简单(相比 TCC)
  • ✅ 可以基于事件驱动异步调用

缺点

  • ❌ 缺乏隔离性(可能出现脏读、脏写)
  • ❌ 补偿逻辑复杂
  • ❌ 软状态持续时间不确定
  • ❌ 时效性较差

适用场景

  • 长事务场景
  • 业务流程较长
  • 参与者包含第三方系统
  • 对实时一致性要求不高

6. 本地消息表

原理

通过在本地数据库中引入消息表,将业务操作和消息记录放在同一个本地事务中,确保两者的原子性。

架构图

┌─────────────────────────────────┐
│  服务 A                          │
│  ┌───────────────────────────┐  │
│  │  本地数据库                 │  │
│  │  ┌─────────────┐           │  │
│  │  │  业务表      │           │  │
│  │  └─────────────┘           │  │
│  │  ┌─────────────┐           │  │
│  │  │  消息表      │           │  │
│  │  │ (msg_id,    │           │  │
│  │  │  content,   │           │  │
│  │  │  status)    │           │  │
│  │  └─────────────┘           │  │
│  └───────────────────────────┘  │
│          |                       │
│          v                       │
│  ┌───────────────┐               │
│  │ 消息发送服务   │               │
│  └───────────────┘               │
└─────────────┼───────────────────┘
              |
              v
        消息队列 (MQ)
              |
              v
┌─────────────┴───────────────────┐
│  服务 B                          │
│  ┌───────────────┐               │
│  │ 消息消费者     │               │
│  └───────────────┘               │
└─────────────────────────────────┘

工作流程

步骤 1:服务 A 执行本地事务

BEGIN TRANSACTION;

-- 业务操作
UPDATE account SET balance = balance - 100 WHERE id = 1;

-- 插入消息记录
INSERT INTO message_table (msg_id, content, status, create_time)
VALUES ('msg_001', '{"accountId": 1, "amount": 100}', 'PENDING', NOW());

COMMIT;

步骤 2:定时任务扫描消息表

@Scheduled(fixedRate = 1000) // 每秒执行一次
public void scanMessageTable() {
    // 查询待发送的消息
    List<Message> messages = messageDao.findByStatus("PENDING");

    for (Message message : messages) {
        try {
            // 发送到消息队列
            mqProducer.send(message.getContent());

            // 更新消息状态为已发送
            message.setStatus("SENT");
            messageDao.update(message);
        } catch (Exception e) {
            log.error("发送消息失败: {}", message.getMsgId(), e);
            // 重试逻辑(可以增加重试次数字段)
        }
    }
}

步骤 3:服务 B 消费消息

@RabbitListener(queues = "order.queue")
public void handleMessage(String messageContent) {
    try {
        // 解析消息
        TransferInfo info = JSON.parseObject(messageContent, TransferInfo.class);

        // 执行业务操作(幂等处理)
        accountService.addBalance(info.getAccountId(), info.getAmount());

        // 返回 ACK,消息从队列中删除
    } catch (Exception e) {
        log.error("处理消息失败: {}", messageContent, e);
        // 返回 NACK,消息重新入队或进入死信队列
    }
}

关键点

1. 本地事务保证原子性

业务操作和消息插入在同一个数据库事务中,要么都成功,要么都失败。

2. 消息发送可靠性

  • 定时任务扫描未发送的消息
  • 支持重试机制
  • 消息状态管理(PENDING、SENT、FAILED)

3. 消息消费幂等性

消息可能会被重复消费,必须保证幂等:

public void addBalance(String accountId, BigDecimal amount, String msgId) {
    // 检查消息是否已处理
    if (processedMessageDao.exists(msgId)) {
        log.info("消息已处理,跳过: {}", msgId);
        return;
    }

    // 执行业务操作
    Account account = accountDao.findById(accountId);
    account.setBalance(account.getBalance().add(amount));
    accountDao.update(account);

    // 记录已处理的消息
    processedMessageDao.insert(msgId);
}

4. 消息表清理

定期清理已成功处理的历史消息。

优点

  • ✅ 实现简单
  • ✅ 不依赖特殊中间件
  • ✅ 可靠性高(基于本地事务)
  • ✅ 适合异步场景

缺点

  • ❌ 需要额外的消息表
  • ❌ 需要定时任务扫描
  • ❌ 消息可能延迟
  • ❌ 不适合实时性要求高的场景

适用场景

  • 对实时性要求不高
  • 异步处理场景
  • 需要保证最终一致性

7. 最大努力通知

原理

最大努力通知是一种非可靠消息的解决方案,允许在通知过程中出现失败,但通过重试机制尽最大努力确保通知的送达。

工作流程

┌──────────┐
│  服务 A   │
│(事务发起) │
└─────┬────┘
      |
      v
[执行本地事务]
      |
      v
[立即发送通知] ───────────┐
      |                   |
      v                   v
  [成功?]           ┌──────────┐
      |              │  服务 B   │
  YES │  NO          │(事务参与) │
      |   |          └─────┬────┘
      v   v                |
   [结束] [记录失败]        v
          |            [处理通知]
          v                |
   [定时重试] ─────────────┘
          |
          v
   [达到最大重试次数?]
          |
      YES │  NO
          |   |
          v   v
      [人工介入]
          [继续重试]

实现方式

方式 1:主动通知 + 重试

public class NotificationService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private NotificationLogDao notificationLogDao;

    // 发送通知
    public void sendNotification(String url, String data) {
        int maxRetries = 5;
        int retryCount = 0;
        boolean success = false;

        while (retryCount < maxRetries && !success) {
            try {
                // 发送 HTTP 请求
                ResponseEntity<String> response = restTemplate.postForEntity(url, data, String.class);

                if (response.getStatusCode().is2xxSuccessful()) {
                    success = true;
                    // 记录成功日志
                    notificationLogDao.insertLog(url, data, "SUCCESS", retryCount);
                }
            } catch (Exception e) {
                retryCount++;
                log.warn("通知发送失败,第 {} 次重试", retryCount, e);

                // 指数退避策略
                try {
                    Thread.sleep((long) Math.pow(2, retryCount) * 1000);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                }
            }
        }

        if (!success) {
            // 记录失败日志,等待人工处理
            notificationLogDao.insertLog(url, data, "FAILED", retryCount);
        }
    }
}

方式 2:被动查询

服务 B 主动查询服务 A 的事务状态。

// 服务 B 定期查询
@Scheduled(fixedRate = 60000) // 每分钟查询一次
public void queryTransactionStatus() {
    List<PendingTransaction> pendingTxs = pendingTxDao.findAll();

    for (PendingTransaction tx : pendingTxs) {
        try {
            // 查询服务 A 的事务状态
            String status = restTemplate.getForObject(
                "http://serviceA/transaction/status?txId=" + tx.getTxId(),
                String.class
            );

            if ("SUCCESS".equals(status)) {
                // 执行本地事务
                processTransaction(tx);
                // 删除待处理记录
                pendingTxDao.delete(tx.getId());
            } else if ("FAILED".equals(status)) {
                // 删除待处理记录
                pendingTxDao.delete(tx.getId());
            }
            // 如果是 PENDING,继续等待
        } catch (Exception e) {
            log.error("查询事务状态失败: {}", tx.getTxId(), e);
        }
    }
}

重试策略

1. 固定间隔重试

重试1:立即
重试2:5秒后
重试3:10秒后
重试4:15秒后

2. 指数退避

重试1:1秒后
重试2:2秒后
重试3:4秒后
重试4:8秒后
重试5:16秒后

3. 自定义策略

重试1:立即
重试2:1分钟后
重试3:5分钟后
重试4:30分钟后
重试5:2小时后

应用场景示例

支付结果通知

┌──────────┐         ┌──────────┐         ┌──────────┐
│  用户端   │         │  商户系统 │         │ 支付平台  │
└─────┬────┘         └─────┬────┘         └─────┬────┘
      |                     |                     |
      |  发起支付            |                     |
      |─────────────────────|────────────────────>|
      |                     |                     |
      |                     |               [处理支付]
      |                     |                     |
      |  支付成功            |                     |
      |<────────────────────|─────────────────────|
      |                     |                     |
      |                     |    [通知商户]        |
      |                     |<────────────────────|
      |                     |                     |
      |                     |   [回复 ACK]         |
      |                     |─────────────────────>|
      |                     |                     |
      |                     | [如果未收到 ACK,重试通知]
      |                     |<────────────────────|
      |                     |                     |
      |                [商户主动查询]                |
      |                     |─────────────────────>|
      |                     |                     |
      |                     |   [返回支付状态]      |
      |                     |<────────────────────|

优点

  • ✅ 实现简单
  • ✅ 适合对实时性要求不高的场景
  • ✅ 接收方可以主动查询
  • ✅ 允许消息丢失(通过重试补偿)

缺点

  • ❌ 不保证实时性
  • ❌ 可能需要人工介入
  • ❌ 需要接收方配合(提供查询接口或接收通知)

适用场景

  • 支付结果通知
  • 第三方系统通知
  • 对实时性要求不高的跨系统通知

分布式事务的发展历程

1970s - 1980s:分布式事务的起源

1976年:Jim Gray 提出事务的概念

  • 定义了事务的 ACID 特性
  • 提出了事务处理的基本理论

1979年:提出两阶段提交协议(2PC)

  • 解决分布式事务一致性问题
  • 成为分布式事务的经典协议

1980s - 1990s:标准化阶段

1991年:X/Open 提出 XA 协议

  • 定义了分布式事务处理的标准接口
  • 被各大数据库厂商支持

1987年:三阶段提交协议(3PC)提出

  • 改进 2PC 的阻塞问题
  • 引入超时机制

2000s:理论突破

2000年:CAP 定理

  • Eric Brewer 提出 CAP 定理
  • 指出分布式系统的三个核心矛盾

2002年:CAP 定理的证明

  • Seth Gilbert 和 Nancy Lynch 证明了 CAP 定理

2008年:BASE 理论

  • 提出柔性事务的理论基础
  • 为最终一致性提供理论支持

2010s:微服务时代的分布式事务

2012年:Saga 模式的流行

  • 长事务解决方案
  • 适合微服务架构

2014年:TCC 模式的广泛应用

  • 补偿型事务
  • 适合高并发场景

2019年:Seata 开源

  • 阿里巴巴开源的分布式事务框架
  • 支持多种事务模式(AT、TCC、Saga、XA)

2020s:云原生时代

分布式事务向云原生演进

  • 支持多云、混合云
  • 与服务网格(Service Mesh)结合
  • 更好的可观测性和监控

事件驱动架构(EDA)的兴起

  • 基于事件的最终一致性
  • 更高的系统解耦
  • 更好的伸缩性

重要论文与理论

经典论文

1. 事务处理的基础

《The Transaction Concept: Virtues and Limitations》

  • 作者:Jim Gray
  • 年份:1981
  • 贡献:定义了事务的 ACID 特性,奠定了事务处理的理论基础

2. 两阶段提交

《Concurrency Control and Recovery in Database Systems》

  • 作者:Philip A. Bernstein, Vassos Hadzilacos, Nathan Goodman
  • 年份:1987
  • 贡献:详细阐述了两阶段提交协议的原理和实现

3. CAP 定理

《Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services》

  • 作者:Seth Gilbert, Nancy Lynch
  • 年份:2002
  • 贡献:证明了 CAP 定理,阐明了分布式系统的根本限制

《CAP Twelve Years Later: How the “Rules” Have Changed》

  • 作者:Eric Brewer
  • 年份:2012
  • 贡献:重新审视 CAP 定理,提出更细粒度的权衡

4. Paxos 算法

《The Part-Time Parliament》

  • 作者:Leslie Lamport
  • 年份:1998
  • 贡献:提出了 Paxos 一致性算法,解决分布式系统的共识问题

《Paxos Made Simple》

  • 作者:Leslie Lamport
  • 年份:2001
  • 贡献:用更简单的方式阐述 Paxos 算法

5. Raft 算法

《In Search of an Understandable Consensus Algorithm》

  • 作者:Diego Ongaro, John Ousterhout
  • 年份:2014
  • 贡献:提出了更易理解的 Raft 一致性算法

6. Saga 模式

《Sagas》

  • 作者:Hector Garcia-Molina, Kenneth Salem
  • 年份:1987
  • 贡献:提出 Saga 长事务处理模式

7. 最终一致性

《Eventually Consistent》

  • 作者:Werner Vogels
  • 年份:2009
  • 贡献:阐述了最终一致性的概念和应用

重要著作

《Designing Data-Intensive Applications》(数据密集型应用系统设计)

  • 作者:Martin Kleppmann
  • 年份:2017
  • 内容:全面讲解分布式系统的数据一致性、事务处理等核心概念

《Distributed Systems》

  • 作者:Maarten van Steen, Andrew S. Tanenbaum
  • 年份:2017
  • 内容:系统阐述分布式系统的理论和实践

应用场景

1. 电商系统

订单处理流程

涉及的服务

  • 订单服务
  • 库存服务
  • 支付服务
  • 优惠券服务
  • 积分服务
  • 物流服务

典型场景

用户下单流程:
1. 订单服务:创建订单
2. 库存服务:扣减库存
3. 优惠券服务:核销优惠券
4. 支付服务:处理支付
5. 积分服务:增加积分
6. 物流服务:创建物流单

推荐方案

  • Saga 模式:适合业务流程长、参与者多的场景
  • TCC 模式:适合对一致性要求较高的场景(如扣库存)
  • 本地消息表:适合异步通知场景(如物流通知)

支付退款

涉及的操作

  • 订单状态回滚
  • 库存恢复
  • 资金退回
  • 积分扣减
  • 优惠券恢复

推荐方案

  • Saga 补偿模式:每个操作都有对应的补偿操作

2. 金融系统

转账业务

涉及的操作

  • 扣减转出账户余额
  • 增加转入账户余额
  • 记录交易流水
  • 更新账户状态

推荐方案

  • XA/2PC:金融业务对一致性要求极高,适合使用强一致性方案
  • TCC 模式:高并发场景下的替代方案

跨行转账

特点

  • 涉及多个银行系统
  • 对一致性要求高
  • 需要支持补偿

推荐方案

  • Saga 模式:支持长事务,支持跨系统
  • 最大努力通知:银行间的通知机制

3. 库存系统

库存扣减

场景

  • 多个订单并发扣减同一商品库存
  • 需要防止超卖
  • 需要支持预占库存

推荐方案

  • TCC 模式:Try 阶段预占库存,Confirm 阶段真正扣减
  • 本地锁 + 分布式锁:保证库存扣减的原子性

库存同步

场景

  • 线上线下库存同步
  • 多仓库库存同步
  • 实时性要求不高

推荐方案

  • 本地消息表:保证消息可靠投递
  • 最大努力通知:允许延迟,支持重试

4. 订单系统

订单创建

涉及的服务

  • 用户服务(验证用户信息)
  • 商品服务(验证商品信息)
  • 库存服务(预占库存)
  • 优惠券服务(验证并锁定优惠券)
  • 订单服务(创建订单)

推荐方案

  • TCC 模式:各服务提供 Try、Confirm、Cancel 接口
  • Saga 模式:通过编排或协调管理流程

订单取消

涉及的操作

  • 更新订单状态
  • 释放库存
  • 释放优惠券
  • 退款(如已支付)

推荐方案

  • Saga 补偿模式:执行一系列补偿操作

5. 物流系统

订单发货

涉及的操作

  • 更新订单状态
  • 创建物流单
  • 更新库存
  • 通知用户

推荐方案

  • 本地消息表:保证消息可靠传递
  • Saga 模式:管理整个发货流程

6. 微服务架构

服务编排

特点

  • 服务数量多
  • 调用链路长
  • 需要高度解耦

推荐方案

  • Saga 事件驱动编排:服务间通过事件通信
  • 分布式事务框架:使用 Seata 等框架统一管理

数据一致性

挑战

  • 服务独立数据库
  • 无法使用本地事务
  • 需要保证最终一致性

推荐方案

  • 事件溯源(Event Sourcing):记录所有事件,通过重放达到一致
  • CQRS(命令查询职责分离):分离读写,异步同步数据

主流解决方案对比

方案对比表

方案 一致性 性能 复杂度 侵入性 适用场景
XA/2PC 强一致 金融核心业务、对一致性要求极高
3PC 强一致 很少使用,理论意义大于实践
TCC 最终一致 高并发、对性能要求高、业务可控
Saga 最终一致 长事务、流程复杂、跨系统
本地消息表 最终一致 异步通知、对实时性要求不高
最大努力通知 最终一致 跨系统通知、允许消息丢失

选型建议

根据业务特点选择

1. 对一致性要求极高(金融核心业务)

  • 首选:XA/2PC
  • 备选:TCC(如果性能是瓶颈)

2. 高并发场景(电商秒杀)

  • 首选:TCC
  • 备选:Saga + 消息队列

3. 长事务场景(订单处理流程)

  • 首选:Saga
  • 备选:TCC(如果需要更好的隔离性)

4. 异步通知场景

  • 首选:本地消息表
  • 备选:最大努力通知(如果允许消息丢失)

5. 跨系统通知(支付回调)

  • 首选:最大努力通知
  • 备选:本地消息表 + MQ

根据技术栈选择

1. 单体应用 + 多数据库

  • XA/2PC(数据库原生支持)

2. 微服务架构

  • Saga 模式(通过协调器或事件驱动)
  • TCC 模式(需要业务改造)

3. 云原生架构

  • 事件驱动架构
  • Saga 事件编排
  • 服务网格集成

根据团队能力选择

1. 团队经验不足

  • 本地消息表(实现简单)
  • 最大努力通知(实现简单)

2. 团队经验丰富

  • TCC(需要深入理解业务)
  • Saga(需要设计补偿逻辑)

3. 使用成熟框架

  • Seata(支持多种模式)
  • ServiceComb(华为开源)

学习资源

开源框架

1. Seata(推荐)

简介:阿里巴巴开源的分布式事务解决方案

特性

  • 支持 AT、TCC、Saga、XA 四种模式
  • 高性能
  • 易于集成(Spring Cloud、Dubbo)

官网:https://seata.io/

GitHub:https://github.com/seata/seata

示例项目

  • Seata Samples:https://github.com/seata/seata-samples

2. Apache ServiceComb Pack

简介:华为开源的分布式事务解决方案

特性

  • 支持 Saga 模式
  • 支持 TCC 模式
  • 基于事件驱动

官网:https://servicecomb.apache.org/

GitHub:https://github.com/apache/servicecomb-pack

3. Hmily

简介:高性能分布式事务 TCC 框架

特性

  • 专注于 TCC 模式
  • 高性能
  • 支持多种 RPC 框架

GitHub:https://github.com/dromara/hmily

4. ByteTCC

简介:基于 TCC 补偿型事务的分布式事务框架

特性

  • 支持 TCC
  • 支持 XA
  • 轻量级

GitHub:https://github.com/liuyangming/ByteTCC

5. EasyTransaction

简介:阿里巴巴开源的柔性事务解决方案

特性

  • 支持 TCC
  • 支持 Saga
  • 支持可靠消息

GitHub:https://github.com/QNJR-GROUP/EasyTransaction

学习文档

官方文档

  1. Seata 官方文档
    • 中文文档:https://seata.io/zh-cn/docs/overview/what-is-seata.html
    • 详细介绍各种事务模式的原理和使用
  2. Spring Cloud 分布式事务
    • 官方文档:https://spring.io/projects/spring-cloud
    • Spring Cloud Alibaba Seata 集成
  3. MySQL XA 事务文档
    • https://dev.mysql.com/doc/refman/8.0/en/xa.html

技术博客

  1. 美团技术团队
    • 《分布式事务的几种解决方案》
    • 《Saga 分布式事务解决方案》
  2. 阿里云技术博客
    • 《分布式事务 Seata 及其三种模式详解》
  3. InfoQ 技术文章
    • 分布式系统相关文章合集

在线课程

  1. 极客时间
    • 《从0开始学架构》(李运华)
    • 《分布式协议与算法实战》(韩健)
  2. 慕课网
    • 《分布式事务实战》
    • 《微服务架构实战》
  3. B站视频
    • 搜索”分布式事务”可找到大量优质视频教程

书籍推荐

入门级

  1. 《分布式系统原理与范型》
    • 作者:Andrew S. Tanenbaum
    • 系统介绍分布式系统的基础知识
  2. 《微服务架构设计模式》
    • 作者:Chris Richardson
    • 详细讲解 Saga 模式等微服务事务处理

进阶级

  1. 《数据密集型应用系统设计》(DDIA)
    • 作者:Martin Kleppmann
    • 深入讲解分布式系统的数据一致性、事务处理
  2. 《分布式系统:概念与设计》
    • 作者:George Coulouris
    • 经典的分布式系统教材
  3. 《大规模分布式存储系统》
    • 作者:杨传辉
    • 阿里巴巴分布式存储实践

高级

  1. 《事务处理:概念与技术》
    • 作者:Jim Gray, Andreas Reuter
    • 事务处理的经典著作
  2. 《Designing Data-Intensive Applications》(英文原版)
    • 作者:Martin Kleppmann
    • 被誉为分布式系统必读书籍

实战项目

1. 电商系统实战

基于 Spring Cloud + Seata 实现电商系统的分布式事务:

项目结构

mall-system
├── order-service      (订单服务)
├── inventory-service  (库存服务)
├── payment-service    (支付服务)
├── account-service    (账户服务)
└── seata-server       (Seata 服务端)

GitHub 参考项目

  • https://github.com/seata/seata-samples/tree/master/springcloud-jpa-seata

2. TCC 模式实战

实现一个基于 TCC 的转账系统:

核心接口

public interface AccountTccService {
    // Try: 冻结金额
    boolean tryDeduct(String accountId, BigDecimal amount);

    // Confirm: 确认扣款
    boolean confirmDeduct(String accountId, BigDecimal amount);

    // Cancel: 取消扣款
    boolean cancelDeduct(String accountId, BigDecimal amount);
}

3. Saga 模式实战

实现一个订单处理的 Saga 流程:

流程设计

创建订单 → 扣减库存 → 处理支付 → 创建物流单
   ↓          ↓          ↓          ↓
取消订单   恢复库存   退款处理   取消物流

社区与论坛

  1. Seata 社区
    • 钉钉群、微信群
    • GitHub Issues
  2. 掘金社区
    • 分布式事务话题
  3. StackOverflow
    • 搜索 “distributed transaction”
  4. Reddit
    • r/distributed
    • r/microservices

常见问题解答

Q1: 什么时候需要使用分布式事务?

需要使用的场景

  • 多个服务需要保证数据一致性
  • 跨数据库的操作需要原子性
  • 微服务架构下的数据一致性问题

不需要使用的场景

  • 单体应用(使用本地事务即可)
  • 可以接受数据不一致的场景
  • 可以通过业务设计避免分布式事务

Q2: 2PC 和 3PC 在实际生产中用得多吗?

2PC(XA)

  • 在传统企业应用中使用较多(如 ERP、银行核心系统)
  • 在互联网公司使用较少(性能原因)
  • 适合一致性要求极高的场景

3PC

  • 生产环境中很少使用
  • 实现复杂,收益不明显
  • 主要用于理论研究

替代方案

  • 互联网公司更多使用 TCC、Saga、本地消息表等柔性事务方案

Q3: TCC 和 Saga 如何选择?

选择 TCC 的场景

  • 对隔离性有要求(需要锁定资源)
  • 业务流程相对简单
  • 性能要求高
  • 可以接受较高的开发成本

选择 Saga 的场景

  • 长事务场景
  • 业务流程复杂(多个步骤)
  • 参与者包含第三方系统
  • 对实时性要求不高

对比总结

  • TCC 更”重”,需要实现三个方法,但提供更好的隔离性
  • Saga 更”轻”,只需实现补偿逻辑,但缺乏隔离性

Q4: 分布式事务会影响性能吗?

性能影响因素

  1. 网络通信:多次网络 RPC 调用
  2. 资源锁定:事务期间锁定资源
  3. 协调开销:事务协调器的开销

不同方案的性能对比

  • XA/2PC:性能最差(强一致性 + 资源锁定)
  • TCC:性能较好(不长时间锁定资源)
  • Saga:性能较好(异步执行)
  • 本地消息表:性能较好(异步)
  • 最大努力通知:性能最好(不保证实时性)

优化建议

  • 减少分布式事务的使用(通过业务设计)
  • 选择合适的事务方案
  • 异步化处理
  • 使用缓存减少数据库访问

Q5: 分布式事务如何保证幂等性?

幂等性的重要性

  • 网络重试可能导致重复执行
  • 消息队列可能重复投递
  • 补偿操作可能被多次调用

实现方式

  1. 唯一约束
    -- 使用数据库唯一索引
    CREATE UNIQUE INDEX idx_order_id ON orders(order_id);
    
  2. 状态机
    // 只有在特定状态才能执行操作
    if (order.getStatus() == OrderStatus.PENDING) {
     order.setStatus(OrderStatus.PAID);
     orderDao.update(order);
    }
    
  3. 分布式锁
    // 使用 Redis 分布式锁
    String lockKey = "order:" + orderId;
    if (redisLock.tryLock(lockKey)) {
     try {
         // 执行业务逻辑
         processOrder(orderId);
     } finally {
         redisLock.unlock(lockKey);
     }
    }
    
  4. 全局唯一 ID
    // 使用雪花算法生成全局唯一 ID
    String transactionId = snowflake.nextId();
    // 每次操作都带上 transactionId
    // 记录已处理的 transactionId
    if (processedIds.contains(transactionId)) {
     return; // 已处理,跳过
    }
    

Q6: 如何监控分布式事务?

监控指标

  1. 事务成功率
    • 成功的事务数 / 总事务数
  2. 事务耗时
    • 平均耗时
    • P95、P99 耗时
  3. 补偿执行率
    • 执行补偿的事务数 / 总事务数
  4. 重试次数
    • 平均重试次数
    • 最大重试次数

监控工具

  1. Seata 控制台
    • 查看全局事务状态
    • 查看分支事务状态
  2. Prometheus + Grafana
    • 采集事务指标
    • 可视化展示
  3. ELK(Elasticsearch + Logstash + Kibana)
    • 日志收集和分析
    • 事务链路追踪
  4. SkyWalking / Zipkin
    • 分布式链路追踪
    • 事务调用关系可视化

Q7: 分布式事务失败如何处理?

失败类型

  1. 业务失败(如余额不足)
    • 执行补偿逻辑
    • 回滚事务
  2. 技术失败(如网络超时)
    • 重试机制
    • 超过最大重试次数后告警
  3. 补偿失败
    • 记录日志
    • 人工介入处理

处理策略

  1. 自动重试
    @Retryable(
     value = {RemoteException.class},
     maxAttempts = 3,
     backoff = @Backoff(delay = 1000, multiplier = 2)
    )
    public void processTransaction() {
     // 业务逻辑
    }
    
  2. 告警通知
    if (retryCount > MAX_RETRY) {
     alertService.sendAlert("分布式事务失败", transactionId);
    }
    
  3. 人工介入
    // 记录到异常表
    exceptionDao.insert(new TransactionException(
     transactionId,
     "补偿失败",
     errorMessage
    ));
    

Q8: 微服务拆分后如何避免分布式事务?

设计原则

  1. 基于业务能力拆分服务
    • 确保单个服务的业务完整性
    • 避免跨服务的强一致性需求
  2. 合理设计服务边界
    • 高内聚、低耦合
    • 将强一致性需求放在同一个服务内
  3. 使用最终一致性
    • 异步消息
    • 事件驱动

实践建议

  1. 延迟拆分
    • 不要过度拆分服务
    • 先做到单体应用的模块化
  2. 合并服务
    • 如果两个服务频繁需要分布式事务,考虑合并
  3. 业务补偿
    • 通过业务手段解决数据不一致
    • 如:积分补发、余额调整

Q9: 分布式事务与 CAP 定理的关系?

关系说明

  1. 强一致性事务(XA/2PC)
    • 选择 CP(一致性 + 分区容错性)
    • 牺牲可用性(阻塞)
  2. 柔性事务(TCC/Saga)
    • 选择 AP(可用性 + 分区容错性)
    • 牺牲一致性(最终一致)

实践建议

  • 根据业务需求在 C 和 A 之间权衡
  • 核心业务选择 CP(如金融)
  • 一般业务选择 AP(如电商)

Q10: 如何测试分布式事务?

测试类型

  1. 功能测试
    • 正常流程测试
    • 异常流程测试(补偿逻辑)
  2. 故障测试
    • 网络故障(超时、断连)
    • 节点故障(协调器、参与者)
    • 部分成功场景
  3. 性能测试
    • 并发压测
    • 长事务测试
  4. 一致性测试
    • 最终一致性验证
    • 数据校验

测试工具

  1. 混沌工程工具
    • Chaos Monkey:随机制造故障
    • Toxiproxy:模拟网络故障
  2. 压测工具
    • JMeter
    • Gatling
  3. 日志分析
    • 检查事务执行日志
    • 验证补偿是否执行

参考资料

  • Seata 官方文档:https://seata.io/
  • Martin Kleppmann《Designing Data-Intensive Applications》
  • CAP 定理:Eric Brewer, 2000
  • Saga 模式:Garcia-Molina & Salem, 1987
  • 分布式系统实践经验总结

提示:本文档持续更新中,如有问题或建议,欢迎反馈。