全局事务服务GTS已进入下线状态,将于2023年7月20日全面停止支持。本文介绍如何将GTS迁移至开源项目Seata以承接分布式事务的需求。
前提条件
安装Seata。
迁移方案
Seata于2019年1月正式开源,提供了涵盖多种事务模式的一站式分布式事务解决方案,符合技术演进的方向。由于目前开源Seata尚未提供对GTS Client的完全支持,因此在开发侧需要参考下文完成GTS到开源Seata的过渡。
依赖迁移
迁移前GTS依赖如下所示。
<dependency>
<groupId>com.taobao.txc</groupId>
<artifactId>txc-client</artifactId>
<version>${gts.sdk.version}</version>
</dependency>
<dependency>
<groupId>com.taobao.txc</groupId>
<artifactId>txc-client-springcloud</artifactId>
<version>${gts.sdk.version}</version>
</dependency>
迁移后Seata依赖如下所示。
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>${seata.version}</version>
</dependency>
seata.version
建议使用1.5.2版本。
配置迁移
迁移前GTS配置如下。
spring.cloud.txc.txcAppName=sc_demo_business
# - txcServerGroup: spring.cloud.txc.txcServerGroup事务分组。
# txc_test_public.1129361738553704.QD 是公网测试的专用事务分组。
# 在阿里云环境运行时,请使用自己在官网开通的事务分组(GTS实例)。
spring.cloud.txc.txcServerGroup=default
# - mode: spring.cloud.txc.mode工作模式。
# AT=1,MT=2,不配置,则默认为1。
# spring.cloud.txc.mode=1
# - url: spring.cloud.txc.url服务发现地址。
# 本地公网测试的服务发现地址,配置如下。
# 在阿里云环境运行时,有默认地址,请删除该配置。
# spring.cloud.txc.url=https://test-cs-gts.aliyuncs.com
# 下面两个配置对应TxcTransactionScaner的accessKey/secretKey两个属性。
# 在阿里云环境运行时,请配置拥有spring.cloud.txc.txcServerGroup指定的事务分组(GTS实例)运行权限的用户的AK/SK。
# 本地公网测试不需要该配置。
#spring.cloud.txc.accessKey=xxxxxxxxx's AK
#spring.cloud.txc.secretKey=xxxxxxxxx's SK
迁移后Seata配置如下所示。
seata.application-id=seata-test
seata.tx-service-group=xxx
seata.registry.type=nacos
seata.registry.nacos.server-addr=xxx
seata.registry.nacos.group=xxx
seata.config.type=nacos
seata.config.nacos.server-addr=xxx
seata.config.nacos.group=seata-xxx
API迁移
常用API映射如下表所示。一般推荐只使用注解方式开启事务(@TxcTransaction/@GlobalTransaction),复杂场景业务可能会使用API手动控制事务。
对比项 | GTS | Seata |
---|---|---|
创建事务(注解) | @TxcTransaction | @GlobalTransaction |
创建事务(API) | TxcTransaction.getInstance(String vgroup, String ak, String sk) | GlobalTransactionContext.getCurrentOrCreate() |
获取事务XID | TxcContext.getCurrentXid() | RootContext.getXID() |
事务挂起 | TxcContext.suspendTxcTransaction() | GlobalTransaction.suspend() |
事务恢复 | TxcContext.resumeTxcTransaction(String xid) | GlobalTransaction.resume(SuspendedResourcesHolder suspendedResourcesHolder) |
事务上下文绑定 | TxcContext.bind(String xid, String nextSvrAddr) | RootContext.bind(String xid) |
事务上下文清除 | TxcContext.unbind() | RootContext.unbind() |
TM初始化 | 无需 | TMClient.init(String applicationId, String transactionServiceGroup) |
RM初始化 | 无需 | RMClient.init(String applicationId, String transactionServiceGroup) |
开启事务 | TxcTransaction.begin(long timeout) | RootContext.unbind() |
二阶段提交事务 | TxcTransaction.commit() | GlobalTransaction.commit() |
二阶段回滚事务 | TxcTransaction.rollback() | GlobalTransaction.rollback() |
AT事务模式
AT模式是通过代理数据源来完成JDBC的增强,如下表所示。
对比项 | GTS | Seata |
---|---|---|
代理数据源 | TxcDataSource | DatasourceProxy |
GTS使用代理数据源需要业务手动组装,方法如下所示。
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
@Bean("dataSourceProxy")
public TxcDataSource dataSourceProxy(DruidDataSource dataSource) {
return new TxcDataSource(dataSource);
}
切换到Seata后,具体会分为3种用法。
- 仅依赖
seata-all
,将上述代码中的TxcDataSource
替换为DatasourceProxy
。 - 仅依赖
seata-all
,去掉dataSourceProxy
的bean
逻辑,加入@EnableAutoDataSourceProxy
注解。 - 依赖
seata-spring-boot-starter
,去掉dataSourceProxy
的bean
逻辑,seata-spring-boot-starter
会将Datasource
接口自动代理为DatasourceProxy
,无需额外处理。
早期GTS与PolarDB-X(DRDS) 5.2以下版本存在集成关系。建议您将DRDS升级至5.3.x+版本。在 5.3版本中,Txc-client集成在DRDS-SERVER中,DRDS通过内部XA模式实现了分库分表的数据一致性。
按照如下方法,判断DRDS是否开启了GTS事务。
连接DRDS-Server,GTS按照库粒度开启,在对应数据库中执行以下SQL。
set autocomit=false;
select last_txc_xid();
commit;
set autocomit=tue;
若执行select last_txc_xid();
的返回中包含8091
,则可以使用GTS来解决DRDS内部的分库分表事务。您还需要升级DRDS版本来替代GTS事务,在此过程中需要注意灰度。
GTS可以处理分库分表事务,若还要处理涉及到跨服务的事务,需要配合Seata一起改造。目前Seata对于DRDS数据库未深度适配,可能存在性能问题。
TCC事务模式
TCC模式仅支持注解的模式使用,除使用@TxcTransaction/@GlobalTransaction创建事务外,还需要额外的API标注分支事务。
对比项 | GTS | Seata |
---|---|---|
分支事务 | @MtBranch | @TwoPhaseBusinessAction |