基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Seata 的三大核心组件:TC、TM、RM 的作用和交互流程

知识点图片

Seata 是一款开源的分布式事务解决方案,它的架构核心由三个重要的组件构成:TC、TM 和 RM。理解这三个组件的作用以及它们之间的交互流程,是掌握 Seata 分布式事务原理的关键。

以下是详细的解析:


一、 三大核心组件的作用

1. TC (Transaction Coordinator) - 事务协调者

  • 角色定位“总指挥”。它是 Seata 的 Server 端,是一个独立部署的服务(通常会做集群高可用)。
  • 核心作用
    • 维护全局事务和分支事务的状态。
    • 负责协调并驱动全局事务的提交(Global Commit)或回滚(Global Rollback)。
    • 生成全局唯一的事务 ID(XID)。

2. TM (Transaction Manager) - 事务管理器

  • 角色定位“发起者 / 项目经理”。它是嵌入在微服务客户端(Client 端)的组件,通常存在于发起全局事务的那个微服务中(例如电商系统中的“订单服务”)。
  • 核心作用
    • 定义全局事务的边界(即从哪里开始,到哪里结束)。
    • 向 TC 申请开启一个全局事务。
    • 根据业务代码的执行结果(成功或抛出异常),向 TC 发起全局提交或全局回滚的指令。

3. RM (Resource Manager) - 资源管理器

  • 角色定位“执行者 / 工人”。它也是嵌入在微服务客户端(Client 端)的组件,存在于每一个参与分布式事务的微服务中(例如“订单服务”、“库存服务”、“账户服务”)。
  • 核心作用
    • 管理分支事务处理的资源(通常是本地数据库)。
    • 向 TC 注册分支事务,并将其纳入 XID 对应的全局事务管辖中。
    • 向 TC 汇报分支事务的执行状态。
    • 接收 TC 的指令,驱动本地事务的提交或回滚(在 AT 模式下,依赖 undo_log 表进行回滚)。

二、 组件之间的交互流程(以 AT 模式为例)

Seata 的事务处理过程本质上是一个两阶段提交(2PC)的演进。
我们以一个经典的电商场景为例:订单服务(TM & RM) 调用 库存服务(RM)

整个交互流程如下:

🚀 第一阶段:执行阶段(Phase 1)

  1. 开启全局事务:业务发起方(订单服务)的 TMTC 申请开启全局事务。TC 创建全局事务后,返回一个全局唯一的 XID
  2. 传递 XID:订单服务在调用库存服务时,会通过 RPC 通信(如 Feign、Dubbo)将 XID 传递给库存服务,将多个服务串联在同一个上下文中。
  3. 执行分支事务 1(订单服务)
    • 订单服务的 RM 拦截数据库操作,向 TC 注册分支事务(携带 XID)。
    • 执行本地 SQL,并记录回滚日志(Undo Log)。
    • 提交本地数据库事务,释放本地锁。
    • TC 汇报分支事务执行状态(成功)。
  4. 执行分支事务 2(库存服务)
    • 库存服务的 RM 获取到 XID,向 TC 注册分支事务。
    • 执行本地 SQL(扣减库存),记录回滚日志(Undo Log)。
    • 提交本地数据库事务,释放本地锁。
    • TC 汇报分支事务执行状态(成功)。

(注意:在第一阶段,各个微服务的本地事务其实已经提交到了数据库,这就是 Seata AT 模式性能高的原因,它不长时间占用数据库锁)

🚀 第二阶段:决断阶段(Phase 2)

这个阶段分为两种情况:全局提交全局回滚

情况 A:所有业务均执行成功(全局提交)

  1. 发起提交决断TM 发现所有的业务逻辑均未报错,向 TC 发起全局提交(Global Commit)请求(携带 XID)。
  2. 通知各个 RMTC 收到请求后,将全局事务状态改为 Committing,并向该 XID 下所有注册的 RM 发送提交指令。
  3. RM 异步清理:各个微服务的 RM 收到提交指令后,会立即给 TC 返回成功。然后把它放入一个异步任务队列中,异步清理本地的 undo_log 记录(因为数据已经确定要持久化了,回滚日志没用了)。

情况 B:某处业务执行失败抛出异常(全局回滚)

  1. 发起回滚决断TM 捕获到了业务异常(比如库存不足),向 TC 发起全局回滚(Global Rollback)请求(携带 XID)。
  2. 通知各个 RMTC 收到请求后,将全局事务状态改为 Rollbacking,并向该 XID 下所有注册的 RM 发送回滚指令。
  3. RM 执行回滚:各个微服务的 RM 收到回滚指令后,根据第一阶段记录的 undo_log(回滚日志),生成反向 SQL(比如第一阶段是 INSERT,这里就是 DELETE)并执行,恢复本地数据。
  4. 汇报结果RM 清理 undo_log,并向 TC 汇报回滚完成。TC 在收到所有 RM 的回滚成功消息后,关闭全局事务。

三、 总结与图解

可以用一张简化的文字图来记忆这个流程:

plaintext
       [微服务 A - 发起方]                       [Seata Server]                   [微服务 B - 参与方]
        TM        RM1                              TC                               RM2
        |          |                                |                                |
        |--- 1.开启全局事务,获取 XID ------------->|                                |
        |          |                                |                                |
        |--- 2.微服务调用,传递 XID (RPC) ------------------------------------------>|
        |          |                                |                                |
        |          |--- 3.注册分支事务(XID) ------->|                                |
        |          |--- 4.执行本地 SQL + UndoLog    |                                |
        |          |--- 5.上报分支状态 ------------>|                                |
        |          |                                |                                |
        |          |                                |<--- 6.注册分支事务(XID) -------|
        |          |                                |     7.执行本地 SQL + UndoLog --|
        |          |                                |<--- 8.上报分支状态 ------------|
        |          |                                |                                |
        |--- 9.业务成功,发起全局 Commit ---------->| (或者业务失败,发起全局 Rollback)  |
        |                                           |                                |
        |                                           |---- 10.通知 RM1 提交/回滚 ---->|
        |<---- 11.通知 RM2 提交/回滚 ---------------|                                |

一句话总结:
TM 是拉开帷幕和决定结局的人;TC 是统筹全局、记录状态的上帝视角;RM 是真正在一线干活,并根据 TC 指令做最后善后(清理日志或反向补偿)的人。而它们之间传递的核心信物就是 XID

00:00
00:00