解决方案
框架
从使用成本的角度来看,直接使用开源的分布式事务框架是比较容易上手的,所以寻找了比较流行的分布式事务框架seata(阿里开源组件)、Hmily(TCC模式)、 tcc-transaction(TCC模式)
seata | hmily | tcc-transaction | |
---|---|---|---|
文档 | 全 | 全 | 不全 |
支持模式 | AT/tcc/saga/XA | tcc | tcc |
star | 18.6k | 3.4k | 4.9k |
对比了几款开源框架,阿里的开源框架seata使用人数最多,支持模式最全,文档也相对较多,所以选用seata进行了试用,下面记录下seata的使用步骤。
seata
原理
Seata的分布式事务解决方案是业务层面的解决方案,只依赖于单台数据库的事务能力。Seata框架中一个分布式事务包含3中角色:
-
Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
(就是我们的Seata-server,用来保存全局事务,分支事务,全局锁等记录,然后会通知各个RM进行回滚或者提交.)
-
Transaction Manager ™: 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
( 也是我们的一个微服务,但是该微服务是一个带头大哥,充当全局事务的发起者(决定了全局事务的开启,回滚,提交等)凡是我们的微服务中标注了@GlobalTransactional ,那么该微服务就会被看成一个TM,同时也是一个RM。)
-
Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。
(可以理解为我们的一个个微服务,也叫事务的参与者)
其中,TM是一个分布式事务的发起者和终结者,TC负责维护分布式事务的运行状态,而RM则负责本地事务的运行。如下图所示:
下面是一个分布式事务在Seata中的执行流程:
- TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。
- XID 在微服务调用链路的上下文中传播。
- RM 向 TC 注册分支事务,接着执行这个分支事务并提交(重点:RM在第一阶段就已经执行了本地事务的提交/回滚),最后将执行结果汇报给TC。
- TM 根据 TC 中所有的分支事务的执行情况,发起全局提交或回滚决议。
- TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。
使用
1.提前搭建nacos作为配置中心和注册中心
2.seata-server搭建
- 下载最新版本1.4.0 seata-server Releases · seata/seata (github.com)
- 修改配置,打开\seata-server-1.4.0\seata\conf文件夹,对file.conf进行修改(主要是对事务日志的配置,mode改为db,并配好的数据库配置,sql语句可在seata/script/server/db at develop · seata/seata (github.com)下载,自行创建数据库导入sql)
## transaction log store, only used in seata-server
store {
## store mode: file、db、redis
mode = "db"
## database store property
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://ip:3306/seata"
user = username
password = password
minConn = 5
maxConn = 100
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
- 对registry.conf进行修改,这里主要进行注册中心和配置中心的配置,此处均选择nacos作为注册中心和配置中心,注册中心和配置中心需要使用其它的组件请自行研究Seata 是什么
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
loadBalance = "RandomLoadBalance"
loadBalanceVirtualNodes = 10
nacos {
application = "seata-server"
serverAddr = "http://ip:8848"
group = "SEATA_GROUP"
#nacos中的命名空间ID
namespace = "a86602c7-0172-4348-9821-e8f28fe4b80e"
cluster = "default"
username = "nacos"
password = "nacos"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "http://ip:8848"
#nacos中的命名空间ID
namespace = "a86602c7-0172-4348-9821-e8f28fe4b80e"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
}
- 修改完配置后,可以启动seata-server,启动脚本在\seata-server-1.4.0\seata\bin 文件夹下面,
- 启动脚本:nohup sh seata-server.sh -p 8091 -h nacosip -m db &
- 可以在nacos上看到,seat