前言
前面两篇文章,已经讲解什么是分布式事务,并且讲解了XA协议和TCC三段提交来解决分布式服务,其实这两种方式都是有缺点,要么比较古老,要么实现起来复杂度搞。那么有没有一个第三方框架,能够直接整合到现有项目,直接把本地事务改成全局分布式事务,类似我们使用Transation注解一样。本文就是讲解新的一种解决方案,也就是阿里提出的Seata。
Seata介绍及其原理
Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案。Seata主要有两种分布式事务实现方案,AT及TCC。
- AT模式主要关注多DB访问的数据一致性,当然也包括多服务下的多DB数据访问一致性问题。
- TCC模式主要关注业务拆分,在按照业务横向扩展资源时,解决微服务间调用的一致性问题。
在Seata分布式事务中,有两个重要的角色:TC(Transaction Coordinator)和TM(Transaction Manager)。TC负责维护全局和分支事务的状态,驱动全局事务提交或回滚。而TM则负责定义全局事务的范围:开始全局事务、提交或回滚全局事务。
其中,二阶段提交是Seata分布式事务的核心机制之一。在第一阶段,Seata会开启一个全局事务,并生成一个全局唯一的XID。然后,Seata会将这个XID通过RPC框架(如Dubbo、Spring Cloud等)传播到业务服务的各个参与者中,并开启相应的分支事务。这些参与者会根据自己的业务逻辑进行数据的修改,并记录相应的undo和redo日志。当所有参与者都执行完毕后,会向TC注册分支,并上报自己的状态。
在第二阶段,如果所有的分支都执行成功,TC会向所有的参与者发送全局提交的命令。否则,如果有任何一个分支执行失败,TC会向所有的参与者发送全局回滚的命令。在接收到全局提交或回滚的命令后,每个参与者会根据自己在第一阶段记录的undo和redo日志进行相应的数据恢复操作。
需要详细了解可以查看seata官网:https://seata.io/zh-cn/docs/overview/what-is-seata.html
Seata实践
代码整合需要注意的是0.7.0以下版本不支持mybatis批量插入,并且Seata适合分布式微服务开发,比较适合当下流行的SpringCloud全家桶。整合步骤:https://seata.io/zh-cn/docs/user/quickstart.html
1)每一个微服务必须创建undo_log
代码语言:sql复制CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2)安装事务协调器:seata-server:https://github.com/seata/seata/releases,下载服务器软件包,也就是Seata服务,将其解压缩。
3)整合sprngcloud
导入依赖spring-cloud-starter-alibaba-seata 导入seata-all-0.7.1,在去找到服务器软件包为seata-all-0.7.1
代码语言:text复制<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
解压并启动seata-server,启动前需要修改Seata两个重要的配置文件
registry.conf:修改配置中心地址,注册中心配置 type = "nacos"
代码语言:text复制 type = "nacos"
nacos {
serverAddr = "120.24.79.44"
namespace = "public"
cluster = "default"
}
file.conf 事务日志存储
所有想要用到分布式事务的微服务使用seata DataSourceProxy代理自己的数据源,并修改service指定,用注册nacos的微服务名称
代码语言:text复制store {
## store mode: file、db
mode = "db"
## file store
file {
dir = "sessionStore"
# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
max-branch-session-size = 16384
# globe session size , if exceeded throws exceptions
max-global-session-size = 512
# file buffer size , if exceeded allocate new buffer
file-write-buffer-cache-size = 16384
# when recover batch read size
session.reload.read_size = 100
# async, sync
flush-disk-mode = async
}
## database store
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
datasource = "dbcp"
## mysql/oracle/h2/oceanbase etc.
db-type = "mysql"
url = "jdbc:mysql://127.0.0.1:3306/seata"
user = "mysql"
password = "mysql"
min-conn = 1
max-conn = 3
global.table = "global_table"
branch.table = "branch_table"
lock-table = "lock_table"
query-limit = 100
}
}
代码语言:javascript复制service {
#vgroup->rgroup
vgroup_mapping.微服务名称-fescar-service-group = "default"
#only support single node
default.grouplist = "127.0.0.1:8091"
#degrade current not support
enableDegrade = false
#disable
disable = false
#unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
max.commit.retry.timeout = "-1"
max.rollback.retry.timeout = "-1"
}
在原有项目的每个微服务,到拷贝这个两个配置文件到源文件目录中
registry.conf
file.conf
启动测试分布式事务
给分布式大事务入口标注 @GlobalTransactional
代码语言:text复制
@GlobalTransactional
public void purchase(String userId, String commodityCode, int orderCount) {
......
}
每个服务小事务管理加 @Transactional
Seata优缺点
Seata是一款优秀的分布式事务解决方案,具有简单易用、高性能、可扩展性和安全性等优点,但也存在一些缺点,如依赖数据库锁、难以管理和缺乏灵活性。
优点:
- 简单易用:Seata提供了丰富的客户端API和文档,使得用户可以很容易地开始使用和管理分布式事务。
- 高性能:Seata的分布式事务解决方案基于两阶段提交协议,具有高性能的特点。
- 可扩展性:Seata支持多种数据源和数据库类型,并且可以轻松地与其他服务集成。
- 安全性:Seata提供了安全机制,例如数据加密和身份验证,以确保分布式事务的安全性。
缺点:
- 依赖数据库锁:Seata的分布式事务解决方案依赖于数据库锁,可能会对数据库的性能产生影响,也就是去全局锁。
- 难以管理:随着业务的发展,分布式事务的数量和管理难度可能会增加,Seata需要用户手动管理和维护这些事务。
- 缺乏灵活性:Seata的分布式事务解决方案是基于两阶段提交协议的,这可能会限制用户的灵活性和可扩展性。
我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!