Spring Cloud Alibaba Seata 分布式事务使用快速入门,Nacos做Seata的注册中心和配置中心
Posted 陆陆通通
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud Alibaba Seata 分布式事务使用快速入门,Nacos做Seata的注册中心和配置中心相关的知识,希望对你有一定的参考价值。
Spring Cloud Seata 分布式事务使用快速入门
特点
1、文档教程详细且提供完整源码及数据库脚本
2、有配套全手敲代码的视频演示教程
使用版本
Spring Cloud Alibaba 2021.1
Nacos 1.4.1
Seata 1.3.0
概念说明:本地事务及分布式事务
本地事务
1、在一个进程中
2、在同一个数据库中
分布式事务及产生
1、多个进程:每个微服务一个进程。
2、每个微服务对应一个数据库或多个微服务对应一个数据库。
3、一个事务需要订单、商品、用户三个微服务上面同时操作成功才算事务全部完成,否则就要回滚。就是说
三个本地事务组成了一个分布式事务。
总结:分布式事务=本地事务1+本地事务2+本地事务N
分布式事务怎么解决
思路:需要有个局外人(事务协调者),统计记录多个本地事务执行情况,所有本地事务全部执行成功,他说成功才算成功。同时如果多个本地事务分别执行过程中,如果哪个出错了,事务协调者要对之前已经执行的操作进行回滚。
举例:
三个人的接力赛,比赛三人配合,某个人只跑完自己的那段不算赢。裁判是根据最终三个人都完成请速度最快来决定胜负。
演示本地事务异常回滚代码
Seata是什么
1、开源的分布式事务解决方案框架
2、提供AT、TCC、SAGA及XA模式
3、目标:对业务无侵入,高性能
4、是裁判记录员(类比)
Seata的AT模式
简化模型:
两阶段提交协议的演变:
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
二阶段:所有本地事务都正常执行就算成功,某个异常时,通过一阶段的回滚日志进行反向补偿。
二阶段提交的详细实现:
第一阶段:
1、不同微服务(相当于一个分支)做了一新增、修改(Update)或删除(Delete)操作,Seata把新增、修改或删除前后的数据记录下来,即原始数据及操作后的数据,分别为前镜像数据和后镜像数据。
2、把这2个数据插入undo_log日志表
3、拿到更新(修改或删除)数据对应id的全局锁
4、将业务更新数据及undo log日志数据同时本地事务提交
5、把提交结果告知给事务协调者(分支提交结果给协调者)
第二阶段:
提交(正常情况):
事务协调者提交事务并且把undo log日志中的数据删除。
回滚(异常情况):
分支回滚请求后,找到对应的undo log日志进行回滚操作
安装使用
版本对应说明
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
Spring Cloud Alibaba 是2021.1,所以Seata使用1.3.0
Seata相关组件下载及配置
下载:
seata-server-1.3.0.zip : 事务协调者服务端 https://github.com/seata/seata/releases/tag/v1.3.0
seata-1.3.0.zip : Seata 1.3配置及脚本 https://github.com/seata/seata/tree/v1.3.0
配置及启动seata-server(事务协助者服务):
1、修改Seata事务协调者数据存储方式
1.1、修改Seata事务协调者服务端的数据存储方式为数据库(默认是file文件)
文件在seata-server\\conf\\file.conf中
store
mode = "db"
db
datasource = "druid"
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata"
user = "root"
password = "123456"
minConn = 5
maxConn = 30
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
1.2、在MySQL中创建seata数据库,然后执行建表语句
seata-1.3.0\\script\\server\\db\\mysql.sql
2、修改Seata事务协调者的注册中心配置
seata-server\\conf\\registry.conf
设置Seata事务协调者服务注册到Nacos上
registry
type = "nacos"
nacos
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = "e98fe52a-5a5d-4c55-98b8-cb867e045e18" //在Nacos中新建的seata命名空间的ID
cluster = "default"
username = "nacos"
password = "nacos"
设置Seata事务协调者的配置信息由Nacos的配置中心进行管理
config
type = "nacos"
nacos
serverAddr = "127.0.0.1:8848"
namespace = "e98fe52a-5a5d-4c55-98b8-cb867e045e18"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
3、添加Seata的配置信息到Nacos配置中心上
3.1、把seata-1.3.0\\script\\config-center\\config.txt中所有配置信息添加到Nacos配置中心上
修改33行及40到45行
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
service.vgroupMapping.my_test_tx_group=default
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
store.mode=db
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true
store.db.user=username
store.db.password=password
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
store.redis.host=127.0.0.1
store.redis.port=6379
store.redis.maxConn=10
store.redis.minConn=1
store.redis.database=0
store.redis.password=null
store.redis.queryLimit=100
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
操作:
进入seata-1.3.0\\script\\config-center\\nacos目录,会看到nacos-config.py和nacos-config.sh两个文件,其中nacos-config.sh即为把seata-1.3.0\\script\\config-center\\config.txt文件中的所有配置信息推送到Nacos配置中心的脚本工具。
其原来为执行Nacos的发布配置接口。https://nacos.io/zh-cn/docs/open-api.html
在此目录下开启Git base窗口,执行如下命令
$ sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t 命名空间ID -u 用户名称 -w 密码
说明:Git base创建打开需要安装Git客户端 ,下载地址:https://git-scm.com/downloads
4、启动事务协调者
执行seata-server\\bin\\seata-server.bat
分布式事务代码案例演示:
微服务调用链路图:
1、建库建表
创建3个数据库及对应的表(其中业务微服务不需要创建数据库)
数据库:
stock_tbl表、undo_log表
CREATE TABLE `stock_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
seata-1.3.0\\script\\client\\at\\db\\mysql.sql
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
seata_lutong_account数据库
account_tbl表、undo_log表
CREATE TABLE `account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`money` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
seata_lutong_order数据库
order_tbl表、undo_log表
CREATE TABLE `order_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT '0',
`money` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
2、创建微服务代码
新建stock-service微服务
添加配置:
server:
port: 8024
spring:
application:
name: stock-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: e98fe52a-5a5d-4c55-98b8-cb867e045e18
group: SEATA_GROUP
datasource:
url: jdbc:mysql://localhost:3306/seata_lutong_stock
driverClassName: com.mysql.jdbc.Driver
username: root
password: 123456
seata:
application-id: stock-service
tx-service-group: seata-storage-tx-group #事务分组
config:
type: nacos
nacos:
namespace: e98fe52a-5a5d-4c55-98b8-cb867e045e18
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
username: nacos
password: nacos
registry:
nacos:
application: seata-server
group: SEATA_GROUP
namespace: e98fe52a-5a5d-4c55-98b8-cb867e045e18
username: nacos
password: nacos
server-addr: 127.0.0.1:8848
3、在Nacos中添加配置项目:
同样的方法编写account-service、order-service、business-service
编写代码较多,可以观看视频来学习操作(这节视频设置免费的,如下链接)
https://download.csdn.net/course/detail/36097
4、Seata使用避坑
1、endpoint format should like ip:port异常
service.vgroupMapping.事务分组名称=default或者在application.yml中添加也可以。
如果不添加会出现如下错误:
Failed to get available servers: endpoint format should like ip:port
java.lang.IllegalArgumentException: endpoint format should like ip:port
2、undo_log插入异常
要设置undo_log日志表的branch_id字段为主键(原来的脚本是没有设置的)
io.seata.common.exception.NotSupportYetException: undo_log needs to contain the primary key.
视频和示例代码获取
视频教程地址:
https://download.csdn.net/course/detail/36097
源码下载地址:
https://github.com/laolujava/spring-cloud-alibaba-tutorial
以上是关于Spring Cloud Alibaba Seata 分布式事务使用快速入门,Nacos做Seata的注册中心和配置中心的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud Alibaba系列教程——Spring Cloud Alibaba开篇
spring boot 整合spring cloud alibaba
spring boot 整合spring cloud alibaba
深度剖析Spring Cloud Alibaba系列——如何兼容Spring Cloud
Spring Cloud Alibaba Sentinel集成
五分钟带你玩转spring cloud alibaba越玩越溜!实战Spring Cloud Alibaba Sentinel