菜鸟AI - 让提示词生成更简单! 全站导航 全站导航
AI工具安装 新手教程 进阶教程 辅助资源 AI提示词 热点资讯 技术资讯 产业资讯 内容生成 模型技术 AI信息库

已有账号?

首页 > AI教程 > SEATA从Server到Golang Client全链路走读详解
进阶教程 综合资讯

SEATA从Server到Golang Client全链路走读详解

2026-06-08
阅读 0
热度 0
作者 菜鸟AI编辑部
摘要

摘要

SEATA通过TC协调全局事务,Golang客户端实现AT、TCC、XA、Saga模式。AT模式使用UndoLog和全局锁保

SEATA在解决什么问题?

想象一下,当微服务架构落地之后,一个看似简单的下单操作,背后却要跨多个服务、多个数据库。扣库存、扣余额、创建订单——这些动作分散在不同的服务里,任何一个环节失败,前面的操作都得撤回。这正是分布式事务要解决的核心难题。

SEATA 是怎么搞定这件事的?其实思路很清晰:

  • TC(事务协调器):也就是 Seata Server,目前用 Ja va 实现(Seata Go 是它的 Golang 客户端)。它的职责是维护全局事务和分支事务的状态,最后决定是提交还是回滚。
  • TM(事务管理器):事务的发起方。在 Go 生态里,就是调用 tm.WithGlobalTx() 的那个服务。
  • RM(资源管理器):每个参与分布式事务的服务里都有这个角色,负责管理本地事务、向 TC 注册分支,并执行 TC 下发的 Commit/Rollback 指令。

Golang Client 启动

如果你翻过 incubator-seata-go-samples 这个仓库,会发现每个 sample 的第一行几乎都是 client.InitPath("../../conf/seatago.yml")。这行代码背后藏着不少事情。

详细拆解几个关键节点:

  1. 服务发现:Go Client 得先知道 TC Server 在哪,服务发现必须先行。
  2. RM 初始化:这部分最重——得建立到 TC 的 TCP 长连接(基于 dubbo-getty),注册消息处理器来接收 TC 的回调指令(Commit/Rollback),还要初始化四种事务模式各自的资源管理器。
  3. 数据源袋里:这是 AT 和 XA 模式的基础,通过 Golang 的 database/sql/driver 接口注册自定义 Driver,所有 SQL 语句都会经过 Seata 的袋里层。

WithGlobalTx 全流程

这应该算是 Seata Go 最重要的 API,贯穿一个全局事务的生命周期。

事务传播机制

WithGlobalTx 支持类似 Spring 的事务传播语义。当一个全局事务内部又调用了 WithGlobalTx 时,其传播级别决定了行为:

传播级别已有事务无事务
Required(Default)加入当前事务新建事务
RequiresNew挂起当前,新建事务新建事务
NotSupported挂起当前,无事务执行无事务执行
Supports加入当前事务无事务执行
Never抛异常无事务执行
Mandatory加入当前事务抛异常

角色区分:Launcher & Participant

在 Seata 中,发起全局事务的服务叫 Launcher,被调用的下游服务叫 Participant。只有 Launcher 有权提交或回滚全局事务,Participant 只负责执行本地分支。这个区分在 commitOrRollback 中语义非常清晰——Participant 直接跳过二阶段操作。

XID 传播

XID 是全局事务的唯一标识,格式类似 192.168.1.1:8091:123456789。它必须贯穿整个调用链,否则下游事务就不知道自己是哪个全局事务的一部分。

Seata Go 通过中间件或拦截器来实现 XID 的透明传播。业务代码完全不用操心 XID 怎么传——只要引入对应框架的中间件,XID 就会自动跟请求走。Gin 走 HTTP Header,gRPC 用 Metadata,Dubbo 用 Attachment,最终都汇入 Seata Context。

AT 模式

AT 模式是 Seata 用得最多的模式,业务侵入也最小。核心思想很简单:在执行 SQL 前后自动记录数据快照(UndoLog),回滚时用快照恢复。

先说 SQL 袋里层。通过实现 Go 标准库的 database/sql/driver 接口,注册自定义的 Driver。应用使用 sql.Open("seata-at", dsn) 时,所有 SQL 都会经过 ATConn 袋里。袋里层根据 SQL 类型(INSERT/UPDATE/DELETE/SELECT FOR UPDATE)选择不同的 Executor。

接着是 UndoLog 结构。每条 undo log 都包含 beforeImage 和 afterImage。前者是执行前快照,后者是执行后。回滚时用 beforeImage 生成反向 SQL——UPDATE 变回原值,INSERT 变 DELETE,DELETE 变 INSERT。

再看全局锁。AT 模式在注册分支时,会向 TC 申请行锁(lock keys),防止多个全局事务同时修改同一行数据。这是 AT 模式保证隔离性的关键。

最后是异步提交。二阶段提交时,AT 模式只需要删除 undo log,不涉及业务操作,所以 TC 可以异步批量处理,效率很高。

TCC 模式

TCC 模式把事务控制权完全还给业务。开发者需要为每个参与方实现三个方法:Try(预留资源)、Confirm(确认提交)、Cancel(取消回滚)。

使用时,需要实现下面接口方法:

方法作用调用时机
Prepare(ctx, params)预留资源(如冻结库存)一阶段,业务主动调用
Commit(ctx, bac)确认提交(如扣减冻结库存)二阶段,TC 驱动
Rollback(ctx, bac)取消回滚(如释放冻结库存)二阶段,TC 驱动
GetActionName()返回资源标识注册时使用

然后通过 tcc.NewTCCServiceProxy(service) 创建袋里,袋里会自动向 TC 注册资源。业务代码只需要在全局事务内调用 proxy.Prepare(),二阶段的 Confirm/Cancel 由 TC 回调触发。

一个经典问题是悬挂问题:如果 Try 请求因为网络延迟还没到达,TC 已经超时触发了 Cancel,之后 Try 请求才到达然后执行。Seata Go 用 Fence 机制来解决,在数据库中维护一张 tcc_fence_log 表,记录每个分支事务的阶段状态,通过本地事务保证幂等性和防止悬挂。

XA 模式

XA 是 DB 层面的分布式事务标准协议,与 AT 模式不同,XA 模式不需要 undo log,依赖 DB 自身的 XA 事务支持。

简单对比 AT 和 XA 模式:

维度AT 模式XA 模式
锁粒度全局锁(Seata 管理)数据库锁(DB 管理)
一阶段锁释放本地事务提交后释放 DB 锁Prepare 后仍持有 DB 锁
一致性最终一致强一致
回滚方式undo log 反向补偿数据库原生 XA ROLLBACK

简单来讲,AT 牺牲了一点一致性来换取高性能,一阶段时就释放 DB 锁。相反,XA 牺牲性能来换取强一致,锁会一直持有到二阶段结束。

Saga 模式

Saga 模式适合长事务场景,通过状态机来编排正向操作和补偿操作。Seata Go 实现了完整的状态机引擎 ProcessCtrlStateMachineEngine

流程定义用 JSON 格式的 statelang,类似 AWS Step Functions。

状态类型作用
ServiceTask调用一个服务方法,可配置补偿方法
Choice条件分支,根据表达式选择下一步
CompensationTrigger触发已执行状态的补偿
Succeed / Fail终态
SubStateMachine嵌套调用另一个状态机

TC Server

前面讲完了 Go Client,下面看看 Seata Server 是怎么处理这些请求的。

DefaultCoordinator 是 TC Server 的入口,处理所有来自 TM/RM 的 RPC 请求。同时管理一组定时任务:

定时任务职责
retryRollbacking重试回滚中的事务
retryCommitting重试提交中的事务
asyncCommitting处理异步提交(AT 模式)
timeoutCheck检测超时事务并触发回滚
undoLogDelete清理过期的 undo log

DefaultCore 是事务处理核心,内部维护了一个 CORE_MAP,按 BranchType 映射到不同的 AbstractCore 实现(ATCore、TCCCore、XACore、SagaCore)。所有分支级别的操作(register、commit、rollback)都委托给对应模式的 Core 处理。

全局事务状态流转

  1. 异步提交:如果所有分支都支持异步提交(AT 模式的二阶段只需删除 undo log),TC 会直接标记为 AsyncCommitting,由后台定时任务批量处理,吞吐量更高。
  2. 超时:TC 有专门的定时任务扫描超时事务。一旦发现超时,直接将状态改为 TimeoutRollbacking,触发回滚流程。
  3. Raft 集群:TC 支持 Raft 模式部署,通过 RaftCoordinator 实现 leader 选举和状态同步,保证 TC 自身的高可用。

RPC 通信

Go Client 和 TC Server 之间的通信基于 TCP 长连接,Go 端使用 dubbo-getty。

通信协议的消息类型覆盖了所有事务操作:

消息方向消息类型说明
Client → TCGlobalBeginRequestTM 开启全局事务
Client → TCGlobalCommitRequestTM 提交全局事务
Client → TCGlobalRollbackRequestTM 回滚全局事务
Client → TCBranchRegisterRequestRM 注册分支事务
Client → TCBranchReportRequestRM 报告分支状态
Client → TCGlobalLockQueryRequestRM 查询全局锁
Client → TCRegisterRMRequestRM 注册资源
TC → ClientBranchCommitRequestTC 驱动分支提交
TC → ClientBranchRollbackRequestTC 驱动分支回滚

Client 端的消息处理器在初始化时注册:rmBranchCommitProcessor 处理提交回调,rmBranchRollbackProcessor 处理回滚回调。收到 TC 的指令后,处理器会根据 BranchType 找到对应的 ResourceManager,执行实际的 Commit/Rollback,然后将结果通过 Response 返回给 TC。

完整请求链路

最后,通过一个请求的完整处理链路串联上述所有内容:

来源:互联网

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

同类文章推荐

相关文章推荐

更多