Seata Go客户端不支持AT模式,仅支持XA和TCC模式;需手动初始化TM/RM、配置注册中心、启用数据库XA支持,并严格遵循XA事务隔离级或TCC接口签名规范。

Seata Go客户端不支持AT模式,只能用XA或TCC
Go语言官方没有维护Seata的AT模式客户端,seata-golang项目仅支持XA和TCC两种模式。如果你依赖AT模式(自动代理数据源、SQL解析、全局锁等),这条路走不通——AT的底层能力严重依赖Java生态的字节码增强和Spring AOP,Go runtime不具备对应机制。
实际能用的路径只有两条:
- 用
TCC模式:自己实现Try/Confirm/Cancel三个方法,业务侵入强但可控 - 用
XA模式:依赖数据库原生XA支持(如MySQL 5.7+、PostgreSQL),由Seata Server协调两阶段提交,Go端只需调用标准database/sql的BeginTx并传入sql.TxOptions{Isolation: sql.IsolationLevel(xa.IsolationLevel)}
初始化Seata Go客户端需手动注册TM/RM并连接Server
seata-golang不是开箱即用的SDK,必须显式启动TM(Transaction Manager)和RM(Resource Manager)组件,并配置指向Seata Server的地址。漏掉任一环节都会导致GlobalTransaction.Begin超时或BranchRegister失败。
关键步骤包括:
立即学习“go语言免费学习笔记(深入)”;
- 调用
client.InitClient()前,先设置config.SetConfigStore(&config.FileConfigStore{Path: "registry.conf"}),其中registry.conf必须包含service.vgroupMapping.my_test_tx_group = "default"和registry.type = "nacos"(或其他注册中心) - 启动TM:调用
tm.Start(),否则GlobalTransaction.Begin会卡在获取transactionId - RM需绑定具体DB连接:用
rm.RegisterResource(&mysql.MySQLResourceManager{...}),且该DB实例必须已开启XA(MySQL需SET GLOBAL innodb_support_xa = ON)
XA模式下Go事务必须用sql.TxOptions.IsolationLevel透传XA标志
普通db.Begin()无法触发XA分支注册,Seata RM只识别带xa.IsolationLevel的事务。如果忽略这点,事务会本地提交成功,但Seata Server里查不到branch record,全局事务无法回滚。
正确写法示例:
import "github.com/seata-go/seata/pkg/xa"
tx, err := db.BeginTx(ctx, &sql.TxOptions{
Isolation: sql.IsolationLevel(xa.IsolationLevel),
})
if err != nil {
return err
}
// 后续执行SQL...
注意:xa.IsolationLevel是seata-golang定义的特殊值(非标准sql.Level*),硬编码为0x1000,必须用它,不能用sql.LevelRepeatableRead之类。
TCC模式需严格对齐Try/Confirm/Cancel参数与返回值
TCC接口定义在tcctypes.TccService中,三个方法签名必须完全匹配:参数类型、顺序、是否指针,以及返回error。任何不一致都会导致Seata Server反序列化失败,日志里出现java.lang.ClassNotFoundException或method not found。
常见踩坑点:
-
Try方法参数必须是struct指针(如*TransferRequest),不能是值类型,否则Confirm/Cancel收不到原始数据 -
Confirm和Cancel必须声明为func(*TransferRequest) error,即使内部没用到参数也要保留,否则Go反射找不到方法 - 所有TCC服务必须提前注册:
tcc.RegisterTccService("transfer", &TransferServiceImpl{}),且服务名要和@TwoPhaseBusinessAction注解里的name一致
复杂点在于Confirm/Cancel的幂等性要自己保证,Seata只负责调用,不校验是否已执行过。这个逻辑不在框架里,容易被忽略。


















