一、seata 与 nacos 集成
seata下载地址:https://github.com/seata/seata,在这里我们使用nacos作为seata的注册中心和配置中心,不再使用seata默认的file存储方式。
1、由于seata
使用mysql
作为db
高可用数据库,故需要在mysql
创建一个ry-seata
库,并导入数据库脚本,即将server/db/mysql 脚本导入数据库,修改conf/registry.conf 将注册中心和配置中心配置为nacos
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = "seata"
cluster = "default"
username = "nacos"
password = "nacos"
}
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = "seata"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
appId = "seata-server"
apolloMeta = "http://192.168.1.204:8801"
namespace = "application"
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
2、将seata 服务的、客户端的配置参数导入 nacos 配置参数在script\config-center\config.tx
service.vgroupMapping.beijing=default
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3307/ry-seata?useUnicode=true
store.db.user=root
store.db.password=root
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
执行script\config-center\nacos\nacos-config.sh 即可导入nacos中。
完成上述步骤即可启动seata 执行bin\seata-server.bat即可,可在nacos 验证是否成功。
注意:由于使用nacos
作为注册中心,所以conf
目录下的file.conf
无需理会。然后就可以直接启动bin/seata-server.bat
,可以在nacos
里看到一个名为seata-server
的服务了。seata将会从nacos读取数据库连接信息来连接数据库,配置参数是响应式的。
二、Springcloud Alibaba 集成 seata
每个业务项目中创建表 undo_log ,执行脚本script\client\at\db\mysql.sql 即可。
导入seat依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
配置application.yml
seata:
enabled: true
# Seata 应用编号,默认为 ${spring.application.name}
application-id: ${spring.application.name}
tx-service-group: beijing # Seata 事务组编号,用于 TC 集群名
registry: #配置seata的注册中心 ,告诉 seata client怎么去访问seata server
type: nacos
nacos:
application: seata-server #seata所在的服务名,如果没有修改 可以不配置
server-addr: 127.0.0.1:8848
namespace: seata
username: nacos
password: nacos
config: # 读取关于client的配置参数
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: "SEATA_GROUP"
namespace: "seata2"
username: "nacos"
password: "nacos"
然后在要分布式事务的方法上加上 @GlobalTransactional 注解即可。
nacos: 注意:namespace 、vgroupMapping 要对应正确
三、AT模式
AT 模式的一阶段、二阶段提交和回滚均由 Seata 框架自动生成,用户只需编写“业务 SQL”,便能轻松接入分布式事务,AT 模式是一种对业务无任何侵入的分布式事务解决方案
在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
二阶段提交:
二阶段如果是提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。
二阶段回滚:
二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。