跳转至

Seata

Seata 场景有哪些角色呢? 它们的作用?⭐️⭐️

TC - Transaction Coordinator (事务协调器): 它是独立的中间件服务端(Seata-Server)。负责维护全局事务的运行状态,接收来自 TM 的请求来开始、提交或回滚全局事务,并与 RM 通信来驱动分支事务的提交或回滚。

TM - Transaction Manager (事务管理器): 嵌入在业务代码中(通常就是那个加了 @GlobalTransactional 注解的微服务)。它负责定义全局事务的边界。并且负责与 TC 配合来完成全局事务的管理

RM - Resource Manager (资源管理器): 控制分支事务的资源(通常是数据库)。它负责向 TC 注册分支事务、汇报分支事务的状态,并接收 TC 的指令来驱动本地事务的提交或回滚。

  • TMTC 申请开启一个全局事务,TC 返回一个全局唯一的 XID
  • RM 带着这个 XID 执行本地业务,并向 TC 汇报:“我这部分准备好了”。
  • TM 根据业务结果,请求 TC 对这个 XID 进行全局提交或回滚。
  • TC 调度 XID 下所有的 RM,指令它们同步完成提交或回滚。

讲一下 Seata AT 模式的工作过程(两个阶段)⭐️

  • 一阶段(准备阶段)

    • Seata 会拦截业务 SQL,在更新前先查一下数据长什么样(Before Image),更新后再查一下长什么样(After Image)。
    • 把这两份快照存到数据库的 undo_log 表里,然后直接无需像 XA 模式必须要等“总指挥”(事务管理器)发送“可以提交”的指令,而是直接提交本地事务, 释放数据库锁。
  • 二阶段(提交/回滚)

    • 如果成功:异步删除 undo_log 记录就行了,性能很高。
    • 如果失败:根据 undo_log 里的 Before Image 把数据还原回去。

AT 模式是怎么解决“脏写”的?(全局锁机制)⭐️

既然一阶段本地事务就提交了,别的线程进来改了数据怎么办?

  • 核心武器全局锁 (Global Lock)
  • 流程:在一阶段本地提交前,分支事务必须向 TC(事务协调器)申请这行数据的“全局锁”。
  • 逻辑:如果申请不到,说明别的事务正在改这行数据,本地事务必须重试或等待。
  • 重点:这样就保证了在分布式环境下,同一时间只有一个事务能修改这行数据,避免了脏写。

在 AT 模式下,虽然一阶段本地事务提交后释放了数据库层面的行锁(DB Lock),但 TC(事务协调器)侧的全局锁(Global Lock)并未释放。其他受 Seata 管理的线程如果尝试修改同一行数据,会因为拿不到全局锁而进入重试或等待。只有等到二阶段完成(无论是全局提交还是全局回滚),全局锁才会被释放,从而在不长时间阻塞数据库连接的前提下,有效避免了脏写。”

如果业务执行时,数据库断电了或者 undo_log 丢了怎么办?⭐️

Seata 在回滚前会做一个校验。它会对比当前数据库里的数据和 undo_log 里的 After Image。如果这两个不一致,说明数据在事务期间被“跳过 Seata”手动改过了(发生了脏写),此时 Seata 会停止回滚,发送告警,需要人工介入。

为什么选 AT 模式而不选 TCC?

“AT 模式对业务无侵入,我只需要在方法上加个 @GlobalTransactional 注解就行了,不需要像 TCC 那样去手写 Try/Confirm/Cancel 三个接口,开发效率极高。对于我们大部分对性能要求不是极端苛刻的业务场景,AT 模式是首选。”

XA 模式你了解吗?⭐️

了解,它是分布式事务的“老大哥”。如果说 Seata AT 模式是“先斩后奏”,那么 XA 模式就是典型的“事事请示”

在 Seata 中使用 XA 模式,其核心动作是完全依赖数据库的。

  • 第一阶段(Prepare)
  • 动作:事务管理器(TC)询问所有参与者(RM):“大家都准备好了吗?”

    • 执行:各数据库执行本地 SQL,但不提交事务。此时,数据库会锁定资源(行锁),等待最后的指令。
  • 第二阶段(Commit/Rollback)

    • 动作:如果大家都说 OK,TC 发送 Commit 指令;只要有一个不行,TC 发送 Rollback。
    • 执行:数据库真正提交或回滚,释放锁。

“XA 模式是基于数据库原生协议的强一致性方案。它的优点是完全交给数据库处理,非常安全;但缺点是锁资源的时间太长,从第一阶段开始直到第二阶段结束,数据库的行锁都不释放。

相比之下,我项目里选用的 AT 模式 通过 undo_log 把‘物理锁’变成了‘逻辑锁’,一阶段就释放了数据库连接,在高并发场景下性能表现更好。”