SpringCloud+Nacos集成Seata-1.7.0分布式事务
前言
项目中需要A服务调用B服务,当A服务方法体内出现异常时,若B服务方法已执行,要求B服务能够进行回滚,需要借助分布式事务实现。Seata是一个比较成熟的分布式事务工具,但官方文档比较简洁,查阅网上资料也版本较多不太统一,在此记录一下集成过程以供下次参考。
环境信息
操作系统:Windows10
JDK:1.8.0_351
SpringCloud版本:2021.0.3
Seata版本:1.7.0
集成过程
一、部署启动seata-server
1. 下载seata-server
从Github上下载所需版本的seata-server-x.x.x.zip
(我这里是1.7.0)后在本机解压。解压后理论上直接运行bin
目录下的seata-server.bat
脚本就可以运行seata服务,linux环境下执行sh seata-server.sh
。但实际项目中肯定要结合数据库和Nacos使用,所以需要修改配置文件。
2. 修改配置文件
需要注意的是,1.5.0之前的版本配置文件是有多个的,都位于conf
文件夹下,如file.conf
,registry,conf
等。在1.5.0版本之后都整合到一个配置文件里了,即application.yml
。以下配置项请按照自己版本查找修改。
以seata-1.7.0为例,打开conf/application.yml
进行修改,重点修改nacos部分配置。
server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:username: seatapassword: seataseata:# nacos配置config:type: nacosnacos:server-addr: 127.0.0.1:8848namespace:group: SEATA_GROUPusername:password:context-path:data-id: seataServer.properties##if use MSE Nacos with auth, mutex with username/password attribute#access-key:#secret-key:registry:# nacos配置type: nacosnacos:application: seata-serverserver-addr: 127.0.0.1:8848group: SEATA_GROUPnamespace:cluster: defaultusername:password:context-path:##if use MSE Nacos with auth, mutex with username/password attribute#access-key:#secret-key:
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login
修改成功后,意味着seata将从nacos获取配置信息,同时注册自身服务到nacos中心。
3. nacos预备
注意到上面配置项中有一项:seata.config.data-id=seataServer.properties
,意思为要读nacos上的seataServer.properties
配置文件,接下来去Nacos
创建该配置文件,注意Group
与第2步中的保持一致,这里是SEATA_GROUP
。
具体配置项是从seata-server-1.7.0/seata/script/config-center/config.txt
粘贴修改而来,其他博客一般建议全粘,笔者查找源码发现那些通用配置项代码里已经写好默认值了,如果不修改没必要都粘过来,这里只使用对我们有用的配置,主要是数据库配置
信息。
#Transaction storage configuration, only for the server.
store.mode=db
store.lock.mode=db
store.session.mode=db#These configurations are required if the `store mode` is `db`.
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://x.x.x.x:3306/ccxi_seata?useSSL=false&useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=password@1234$#11
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
注意数据库连接串和驱动类型一定要写对,如果是Mysql8
要使用com.mysql.cj.jdbc.Driver
。可参考自己Java项目中的配置进行填写。
4. 数据库建表
在上面配置的数据库内,执行seata-server-1.7.0/seata/script/server/db
目录下的sql脚本(根据数据库类型),创建服务端所需的表。
5. 启动seata-server
server端基础配置已经完成,运行bin
下的seata-server.bat
脚本启动服务(linux执行sh seata-server.sh
命令)。出现下述打印即为启动成功。(linux到/root/logs/seata
目录下查看打印日志)
启动成功后,可登录http://ip:7091/#/login
进入seata管理页面,默认用户名和密码都为seata
。
同时,检查nacos上是否成功注册了seata服务:
二、微服务(客户端)集成
1. 添加pom依赖
server已经启动,接下来要把需要使用分布式事务的微服务都注册到server上去。首先在每个微服务内添加pom
依赖。其中seata-spring-boot-starter
这个包为seata核心包,版本号要与自己上述服务端保持一致。此外如果使用SpringCloud
,spring-cloud-starter-alibaba-seata
也必不可少,这个包的版本号最好与所使用SpringCloud
版本保持一致。
<dependencies>...<!-- Seata--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>${alibaba.cloud.version}</version><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions></dependency><dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.7.0</version></dependency>...
</dependencies>
2. 客户端添加seata配置
包引入后,需要在微服务yml
里添加seata客户端所需的配置:
#seata客户端配置
seata:enabled: trueapplication-id: ccxi-abctx-service-group: ccxi_tx_groupservice:vgroup-mapping:ccxi_tx_group: defaultregistry:type: nacosnacos:server-addr: 127.0.0.1:8848namespace: publicgroup: SEATA_GROUPapplication: seata-server
其中tx-service-group
为我们自定义的事务组,名字随便起,但是下面service.vgroup-mapping
下一定要有一个对应你这个名字的映射,映射到default
(seata默认的集群名称)。 nacos
方面,我们仅配置注册项,即registry
下的配置,配置内容与服务端保持一致。这里只配置registry
信息而不再配置config
相关信息,是因为一是作为客户端,没有必要再到nacos读取配置,本来也没多少配置项,且不需要频繁更换。二是如果使用nacos配置,则需要在nacos上再配置tx-service-group
等信息,费力不讨好,且容易与本来的微服务配置形成混淆。
3. 创建undo_log表(仅AT模式)
seata中默认使用的是AT模式
,该模式需求每个客户端库内都存在一张undo_log
表,用于回滚事务时临时记录数据。如使用该模式,需要自行在业务库内创表。
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;
4. 启动客户端
配置完成后,照常启动微服务,如果没有异常,在服务端和客户端分别能看到打印,证明客户端成功注册到了服务端。
5. 测试及使用
在所需要使用分布式事务的方法上添加注解@GlobalTransactional
,当方法内发生异常时,就可以带动所调用微服务进行回滚。
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public void approve(Long id, String taskKey, String comment) throws Exception {Ticket ticket = getTicket(id);// 调用流程微服务进行审批操作processClient.approve(ticket, taskKey, comment, null);// 修改本地工单状态ticket.setState(TicketState.APPROVED);ticketService.saveOrUpdate(ticket);// 记录操作日志processLogger.log(ticket.getBusinessKey(), "审批通过", null);// 抛出异常测试分布式事务throw new Exception("出现异常:测试分布式事务");
}
如果成功触发回滚,两个微服务的控制台均会打印相关信息,重点关注xid
应该为一致的。
服务A日志
服务B日志
补充
按照上面步骤集成完之后如果发现不能正常回滚,应在每个服务的方法内打印下xid,看看是否一致,有没有xid为空的。如果有服务拿不到xid,检查下微服务调用时是否拦截掉了这部分header信息。
System.out.println(RootContext.getXID());
【坑】另外,windows下使用时,服务端经常会自己卡住,需要手动到bat窗口内敲回车来解除卡顿。
作者:鹿里噜哩
链接:https://juejin.cn/post/7257713854745395255
来源:稀土掘金
相关文章:

SpringCloud+Nacos集成Seata-1.7.0分布式事务
前言 项目中需要A服务调用B服务,当A服务方法体内出现异常时,若B服务方法已执行,要求B服务能够进行回滚,需要借助分布式事务实现。Seata是一个比较成熟的分布式事务工具,但官方文档比较简洁,查阅网上资料也…...

任务调度框架-如何实现定时任务+RabbitMQ事务+手动ACK
任务调度框架 Java中如何实现定时任务? 比如: 1.每天早上6点定时执行 2.每月最后一个工作日,考勤统计 3.每个月25号信用卡还款 4.会员生日祝福 5.每隔3秒,自动提醒 10分钟的超时订单的自动取消,每隔30秒或1分钟查询…...

修炼k8s+flink+hdfs+dlink(六:学习k8s)
一:增(创建)。 直接进行创建。 kubectl run nginx --imagenginx使用yaml清单方式进行创建。 二:删除。 kubectl delete pods/nginx 三:修改。 kubectl exec -it my-nginx – /bin/bash 四:查看。 …...

红队专题-从零开始VC++C/S远程控制软件RAT-MFC-[4]客户端与服务端连接
红队专题 招募六边形战士队员服务端编写新建工程server函数创建主线程类获取配置信息运行command 命令头文件里创建引用win32 类库/头文件startsocket 开始监听 类函数添加类StartSocketmysend/myrecv 设置 m_sockCommon 头文件MSGINFO_S 结构体 ThreadMain头文件runflag 启动 …...

Qt Designer生成ui文件,如何转py文件,如何运行
下面将逐步介绍ui文件如何转py文件,怎么运行的具体操作步骤 ui文件转py文件 1.使用Qt Designer生成ui文件,保存到本地 2.输入 cmd ,打开命令行窗口 3.进入ui文件的目录下,文件路径使用你本地存放ui文件的位置 cd /d ui文件路径…...

Python数据挖掘:自动售货机销售数据分析与应用
📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于恒川的日常汇报系列,大家有兴趣的可以看一看 📘相关专栏C语言初阶、C…...

【设计模式】设计模式概述
😀大家好,我是白晨,一个不是很能熬夜😫,但是也想日更的人✈。如果喜欢这篇文章,点个赞👍,关注一下👀白晨吧!你的支持就是我最大的动力!Ǵ…...

第六届“中国法研杯”司法人工智能挑战赛进行中!
第六届“中国法研杯”司法人工智能挑战赛 赛题上新! 第六届“中国法研杯”司法人工智能挑战赛(LAIC2023)目前已发布司法大模型数据和服务集成调度 、证据推理、司法大数据征文比赛、案件要素识别四大任务。本届大赛中,“案件要素…...

关于 passing ‘const xx’ as ‘this’ argument of 的错误
今天在写一个简单的函数时,编译时出现了如下的错误: 这个很简单的函数是这样的: struct bundle_set {uint32_t baseId;uint32_t endId;bool operator< (const bundle_set &a){return baseId < a.baseId;} }; 在网上搜索到都是说什…...

数据结构和算法(13):优先级队列
概述 按照事先约定的优先级,可以始终高效查找并访问优先级最高数据项的数据结构,也统称作优先级队列 优先级队列将操作对象限定于当前的全局极值者。 根据数据对象之间相对优先级对其进行访问的方式,与此前的访问方式有着本质区别…...

面试经典150题——Day15
文章目录 一、题目二、题解 一、题目 135. Candy There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings. You are giving candies to these children subjected to the following requirements: Each chil…...

web APIs——第一天(上)
变量声明的时候建议 const优先,尽量使用const 原因: const语义化更好很多变量我们声明的时候就知道他不会被更改了,那为什么不用const呢?实际开发中也是,比如react框架,基本const如果你有纠结的时候&…...

【Leetcode】215. 数组中的第K个最大元素
一、题目 1、题目描述 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例1: 输入: [3,2,1,5,6,4], k = 2 输出…...

服务器数据恢复-RAID5常见故障的数据恢复方案
raid5阵列常见故障: 1、服务器硬件故障或者RAID阵列卡故障; 2、服务器意外断电导致的磁盘阵列故障; 3、服务器RAID阵列阵列磁盘出现物理故障,如:电路板坏、磁头损坏、盘面划伤、坏扇区、固件坏等; 4、误操作…...

12个VIM编辑器的高级玩法
vim 是一个很好用的编辑器,应用十分广泛。但关于 vim,总有一些你不知道的事情,我们需要持续不断的学习。 我经常使用 vim,也经常在各大社区、论坛看到 vim 专家用户分享经验,今天我们就总结其中常用的一部分ÿ…...

⽜客论坛的笔记
项目描述: 一个基本功能完整的论坛项目。项目主要功能有: 基于邮件激活的注册方式,基于MD5加密与加盐的密码存储方式,登录功能加入了随机验证码的验证,实现登陆状态检查、为游客与已登录用户展示不同界面与功能。支持用户上传头像,…...

JS逆向分析某枝网的HMAC加密、wasm模块加密
这是我2022年学做JS逆向成功的例子,URL:(脱敏处理)aHR0cHM6Ly93d3cuZ2R0di5jbi9hdWRpb0NoYW5uZWxEZXRhaWwvOTE 逆向分析: 1、每次XHR的GET请求携带的headers包括: {"X-ITOUCHTV-Ca-Timestamp":…...

论坛介绍|COSCon'23开源商业(V)
众多开源爱好者翘首期盼的开源盛会:第八届中国开源年会(COSCon23)将于 10月28-29日在四川成都市高新区菁蓉汇举办。本次大会的主题是:“开源:川流不息、山海相映”!各位新老朋友们,欢迎到成都&a…...

Flink学习笔记(三):Flink四种执行图
文章目录 1、Graph 的概念2、Graph 的演变过程2.1、StreamGraph (数据流图)2.2、JobGraph (作业图)2.3、ExecutionGraph (执行图)2.4、Physical Graph (物理图) 1、Graph 的概念 Flink 中的执行图可以分成四层:StreamGraph -> JobGraph -> ExecutionGraph -&g…...

堆-----数据结构
引言 什么是堆?堆是一种特殊的数据结构(用数组表示的树)。 为什么要使用到堆?比如一场比赛,如果使用擂台赛的方式来决出冠军(实力第一),就很难知道实力第二的队伍是什么了。 但是…...

震撼登场 | 拓世科技集团新品亮相成为2023世界VR产业大会全场焦点
在当今世界,新一轮科技革命和产业变革蓬勃发展,虚拟现实作为这一浪潮中的代表性技术,伴随着5G商用及元宇宙概念的迅速兴起,已经成为推动数字经济发展和产业转型升级的关键技术,深刻地改变着人类的生产和生活方式。 10…...

后端接口的查询方式
在与前端对接过程中一直都会遇到一个问题,就是我们后端接口提供好了,自测也通过了,前端却说接口不通,当我们去排查时却发现大都不是接口不通,很多情况是前端使用的姿势不对,比如接口明明写的参数是放到ULR路…...

Maven首次安装配置
所有版本下载地址 http://archive.apache.org/dist/maven/ 配置环境变量 变量名: MAVEN_HOME 值: D:\apache-maven-3.9.5 Path:%MAVEN_HOME%\bin 是否安装成功 mvn -v 出现版本号就安装成功 配置本地仓库 也就是从服务器上下载的JAR包地址&a…...

使用html2canvas将html转pdf,由于table表的水平和竖直有滚动条导致显示不全(或者有空白)
结果: 业务:将页面右侧的table打印成想要的格式的pdf,首先遇到的问题是table表上下左右都有滚轮而html2canvas相当于屏幕截图,那滚动区域如何显示出来是个问题? gif有点模糊,但是大致功能可以看出 可复制…...

EDID详解
文章目录 字节含义一些概念YCC位 文章目录 字节含义一些概念YCC位 字节含义 EDID通常由128个字节组成,这些字节提供了关于显示器的各种详细信息。以下是EDID中每个字节位表示的一般含义: Header(头部): 字节0: Headerÿ…...

浅谈云原生
目录 1. 云原生是什么? 2. 云原生四要素 2.1 微服务 2.2 容器化 2.3 DevOps 2.4 持续交付 3. 具体的云原生技术有哪些? 3.1 容器 (Containers) 3.2 微服务 (Microservices) 3.3 服务网格 (Service Meshes) 3.4 不可变基础设施 (Immutable Inf…...

【K8S】Kubernetes
mesos apache基金会,后来是推特公司 mesos分布式资源管理框架2019淘汰 marathon 容器编排框架 用来调度、编排运行的常驻服务 mesos marathon 容器管理 k8s容器或云平台两种趋势(工资好) 1.K8s是什么 K8s全称为 Kubernetesÿ…...

面试题 01.01. 判定字符是否唯一
题目来源: leetcode题目,网址:面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode) 解题思路: 遍历计数即可。 解题代码: class Solution { public:bool isUnique(string astr) {if(astr.l…...

C++(Qt)软件调试---linux使用dmesg定位程序崩溃位置(14)
C(Qt)软件调试—linux使用dmesg定位程序崩溃位置(14) 文章目录 C(Qt)软件调试---linux使用dmesg定位程序崩溃位置(14)1、前言2、ELF文件3、常用工具4、使用dmesg定位异常位置1.1 异常发生在可执行程序中1.2 异常发生在动态库中 1、…...