Seata 2.x 系列【8】Spring Cloud 集成客户端

有道无术,术尚可求,有术无道,止于术。

本系列Seata 版本 2.0.0

本系列Spring Boot 版本 3.2.0

本系列Spring Cloud 版本 2023.0.0

源码地址:https://gitee.com/pearl-organization/study-seata-demo

文章目录

    • 1. 前言
    • 2. 问题演示
    • 3. 客户端集成
      • 3.1 引入依赖
      • 3.2 配置
      • 3.3 undo_log 表
      • 3.4 开启全局事务
      • 3.5 启动
    • 4. 测试

1. 前言

在前几篇文档中,我们部署好了Seata服务端并集成了Nacos,也搭建了一个微服务项目并实现了电商下单功能,接下来,我们学习如何Spring Cloud集成Seata客户端,并解决分布式事务问题(默认使用的是AT模式)。

2. 问题演示

假如在整个电商下单的流程中,扣除账户余额时,发生了异常:
在这里插入图片描述

    @Override
    @Transactional
    public ObjectResponse decreaseAccount(AccountDTO accountDTO) {
        // 扣减余额
        int account = baseMapper.decreaseAccount(accountDTO.getUserId(), accountDTO.getAmount().doubleValue());
        // 模拟异常
        if (1==1){
            throw new RuntimeException("扣除失败~~");
        }
        ObjectResponse<Object> response = new ObjectResponse<>();
        if (account > 0) {
            response.setStatus(RspStatusEnum.SUCCESS.getCode());
            response.setMessage(RspStatusEnum.SUCCESS.getMessage());
            return response;
        }

        response.setStatus(RspStatusEnum.FAIL.getCode());
        response.setMessage(RspStatusEnum.FAIL.getMessage());
        return response;
    }

操作前,数据库中账户余额为10000,库存为10000,订单数为0,访问http://localhost:8080/business/buy下单接口,账户服务发生异常,由于开启了本地事务,账户回滚 ,订单服务调用账户服务返回异常,也因为开启了本地事务,插入的订单进行了回滚。

但是用于的库存服务本身并没有抛出任何异常,本地事务进行了提交,导致扣减了库存,发生数据不一致问题:
在这里插入图片描述

3. 客户端集成

3.1 引入依赖

在当前案例项目中,以下几个服务都是分布式事务的参与者,所以都需要集成Seata客户端:
在这里插入图片描述
Spring Cloud Alibaba已经提供了Spring Cloud环境下Seata的集成包,只需要引入以下依赖即可:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

Seata客户端依赖为最新的2.0.0版本:
在这里插入图片描述

3.2 配置

在所有服务后台application.yml文件中,添加注册、配置中心:

seata:
  # 配置中心
  config:
    type: nacos
    nacos:
      # 通过 Nacos 获取 Seata 配置(以下配置需要和服务端保持一致)
      namespace: 7032916a-19f1-482e-a3eb-8a62226c2e4d
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      data-id: seata.properties
    # 注册中心
  registry:
    type: nacos
    nacos:
      # 通过 Nacos 服务发现 Seata 服务端(以下配置需要和服务端保持一致)
      # Seata 服务端在Nacos中注册的服务名
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: DEFAULT_GROUP
      namespace: 7032916a-19f1-482e-a3eb-8a62226c2e4d

3.3 undo_log 表

AT模式中,需要在参与全局事务的数据库中添加undo_log表:

CREATE TABLE `undo_log` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `branch_id` bigint NOT NULL,
  `xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL,
  `context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

seata_accountseata_orderseata_stock库中,都新建undo_log表。

3.4 开启全局事务

下单流程由business服务发起,所以该服务即事务的发起方TM,我们在事务发起方法上添加@GlobalTransactional注解开启全局事务:

    @GlobalTransactional
    public Object handleBusiness() {
        ObjectResponse<Object> objectResponse = new ObjectResponse<>();
        // 1. 业务请求数据
        BusinessDTO businessDTO =new BusinessDTO();
        // 省略..........
}

3.5 启动

启动所有业务服务,查看控制台,我们看下Seata相关的一些关键日志。

使用Nacos注册中心:

main] i.s.discovery.registry.RegistryFactory   : use registry center type: nacos

获取到Seata服务端地址并订阅:

main] com.alibaba.nacos.client.naming          : init new ips(1) service: DEFAULT_GROUP@@seata-server@@default -> [{"instanceId":"192.168.142.1#8091#default#DEFAULT_GROUP@@seata-server","ip":"192.168.142.1","port":8091,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"default","serviceName":"DEFAULT_GROUP@@seata-server","metadata":{},"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000,"instanceIdGenerator":"simple"}]
main] com.alibaba.nacos.client.naming          : current ips:(1) service: DEFAULT_GROUP@@seata-server@@default -> [{"instanceId":"192.168.142.1#8091#default#DEFAULT_GROUP@@seata-server","ip":"192.168.142.1","port":8091,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"default","serviceName":"DEFAULT_GROUP@@seata-server","metadata":{},"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000,"instanceIdGenerator":"simple"}]
main] com.alibaba.nacos.client.naming          : [SUBSCRIBE-SERVICE] service:seata-server, group:DEFAULT_GROUP, clusters:default 

使用Netty端口连接到Seata服务端,并发送TM注册请求:

main] i.s.c.r.netty.NettyClientChannelManager  : will connect to 192.168.142.1:8091
main] i.s.core.rpc.netty.NettyPoolableFactory  : NettyPool create channel to transactionRole:TMROLE,address:192.168.142.1:8091,msg:< RegisterTMRequest{version='2.0.0', applicationId='stock', transactionServiceGroup='default_tx_group', extraData='ak=null
digest=default_tx_group,192.168.142.1,1710149283844
timestamp=1710149283844
authVersion=V4
vgroup=default_tx_group
ip=192.168.142.1
'} >

TM注册成功,应用IDaccount(后台服务名),事务分组为default_tx_group(默认的,后续讲解):

main] i.s.c.rpc.netty.TmNettyRemotingClient    : register TM success. client version:2.0.0, server version:2.0.0,channel:[id: 0x9902a1f6, L:/192.168.142.1:53418 - R:/192.168.142.1:8091]
main] i.s.core.rpc.netty.NettyPoolableFactory  : register success, cost 40 ms, version:2.0.0,role:TMROLE,channel:[id: 0x9902a1f6, L:/192.168.142.1:53418 - R:/192.168.142.1:8091]
main] i.s.s.a.GlobalTransactionScanner         : Transaction Manager Client is initialized. applicationId[stock] txServiceGroup[default_tx_group]

数据源初始化完成后,注册RM

main] i.s.s.a.GlobalTransactionScanner         : Resource Manager is initialized. applicationId[stock] txServiceGroup[default_tx_group]
main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@15a0f9
main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
main] i.s.c.r.netty.NettyClientChannelManager  : will connect to 192.168.142.1:8091
main] i.s.c.rpc.netty.RmNettyRemotingClient    : RM will register :jdbc:mysql://127.0.0.1:3306/seata_stock
main] i.s.c.rpc.netty.RmNettyRemotingClient    : register RM success. client version:2.0.0, server version:2.0.0,channel:[id: 0xd20fcff4, L:/192.168.142.1:53423 - R:/192.168.142.1:8091]
main] i.s.core.rpc.netty.NettyPoolableFactory  : register success, cost 8 ms, version:2.0.0,role:RMROLE,channel:[id: 0xd20fcff4, L:/192.168.142.1:53423 - R:/192.168.142.1:8091]

最后可以看到默认开启了AT模式的数据源代理,说明AT是默认开启的事务模型:

main] .s.s.a.d.SeataAutoDataSourceProxyCreator : Auto proxy data source 'dataSource' by 'AT' mode.

4. 测试

重启所有服务后台,访问下单接口,可以看到在库存服务中,虽然没有抛出异常,但是全局事务失败了,进行了回滚操作:
在这里插入图片描述
查看数据库,所有数据一致,集成成功:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/452454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何解决跨网文件交换行为分散难管控等问题?

跨网文件交换是指在不同的网络环境之间&#xff0c;如内网和外网&#xff0c;安全地传输文件的过程。这通常涉及到网络隔离的场景&#xff0c;比如政府机构、金融机构、大型企业等&#xff0c;它们为了安全和保密的需要&#xff0c;会通过物理隔离、逻辑隔离等方式&#xff0c;…

《向量数据库指南》——Milvus Cloud BYOC:为数据安全而生?

最近,整个硅谷都在关注 OpenAI 和 Anthropic 的动态。先是 Anthropic 发布了 Claude 3,剑指 GPT-4,被媒体认为“打破了 OpenAI 不可战胜的神话”。这也点燃了整个科技圈的热情,纷纷期待 OpenAI 放出 GPT-5 应战。随后(美东时间 3 月 5 日),OpenAI 发布一则官方公告,主题…

算法打卡day14|二叉树篇03|104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

算法题 Leetcode 104.二叉树的最大深度 题目链接:104.二叉树的最大深度 大佬视频讲解&#xff1a;二叉树的最大深度视频讲解 个人思路 可以使用层序遍历&#xff0c;因为层序遍历会有一个层数的计算&#xff0c;最后计算到的层数就是最大深度&#xff1b; 解法 迭代法 就是…

基于SWOT的智能手机企业财务战略研究1.62

摘 要 近些年&#xff0c;网络技术日新月异&#xff0c;智能手机深受消费者喜爱&#xff0c;人们通过网络&#xff0c;手机应用&#xff0c;可以极大地方便人们学习&#xff0c;工作等等。由于国家对电信行业的大力支持&#xff0c;中国消费者群体逐步成为最具潜力的手机购买者…

基于单片机的IC 卡门禁系统设计

摘要:针对传统门锁钥匙易丢失、配置不便和忘记携带等问题,提出了一种基于STC89C52 的IC 卡门禁系统设计。该系统以STC89C52 单片机为核心来控制电子锁模块的开关。主要过程是由RFID 模块读取IC卡ID 并通过串口发送至STC89C52 单片机模块,STC89C52 单片机模块可以实现在线对I…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的吸烟检测系统(深度学习+Python代码+PySide6界面+训练数据集)

摘要&#xff1a;本文详细说明了如何利用深度学习开发一个用于监测吸烟行为的系统&#xff0c;并分享了完整的代码实现。该系统采用了先进的YOLOv8算法&#xff0c;同时还使用YOLOv7、YOLOv6、YOLOv5算法&#xff0c;并对它们进行了性能比较&#xff0c;呈现了不同模型的性能指…

VS中配置生成事件

一、为什么需要使用生成事件&#xff1f; 在实际开发过程中&#xff0c;在项目生成DLL后&#xff0c;需要被复制到不同的目录下被引用&#xff0c;很麻烦。 我们可以利用VS中的项目生成事件属性来进行生成后的DLL复制到指定的目录&#xff0c;或者进去其他的操作&#xff0c;比…

C/C++——Tchisla求解器(多线程高性能版本)

前言 之前一篇文章中介绍的使用Python写的Tchisla求解器Python——Tchisla求解器&#xff08;暴力搜索法&#xff09;在我实际使用中有比较大的缺陷&#xff0c;首先是太慢了&#xff0c;对于每日一题中四位数的目标数字&#xff0c;往往搜索数个小时都找不完1~9的全部最优解&…

重学SpringBoot3-ErrorMvcAutoConfiguration类

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-ErrorMvcAutoConfiguration类 ErrorMvcAutoConfiguration类的作用工作原理定制 ErrorMvcAutoConfiguration示例代码1. 添加自定义错误页面2.自定义错误控…

【小白学机器学习8】统计里的自由度DF=degree of freedom, 以及关于df=n-k, df=n-k-1, df=n-1 等自由度公式

目录 1 自由度 /degree of freedom / df 1.1 物理学的自由度 1.2 数学里的自由度 1.2.1 数学里的自由度 1.2.2 用线性代数来理解自由度&#xff08;需要补充&#xff09; 1.2.3 统计里的自由度 1.3 统计学里自由度的定义 2 不同对象的自由度 2.1 纯公式的自由度&#…

汤唯N次被封后,除了人美外,这些也许你没想到!

汤唯N次被封后&#xff0c;除了人美外&#xff0c;这些也许你没想到&#xff01; 引言&#xff1a;影坛的璀璨明星 #李秘书讲写作#注意到&#xff0c;在光鲜亮丽的电影圈&#xff0c;有一位女演员以其独特的气质和深入人心的演技&#xff0c;成为了众多观众心中的璀璨明星。她…

國内linux服务器解决Ollama安装超时

curl -fsSL https://ollama.com/install.sh | sh 执行一直超时 做如下配置&#xff1a; 修改hosts文件&#xff0c;直接将http://github.com做个ip指向。 sudo vim /etc/hosts 输入密码后&#xff0c;按 i 增加以下配置 # github 注意下面的IP地址和域名之间有一个空格 140…

朱熹凭着理学成为天选之子,读书方法也很实用

唐朝是李姓的天下&#xff0c;推行老子的道家思想。同时&#xff0c;佛教兴旺鼎盛。儒家开始没落&#xff0c;失去主要地位。为了恢复儒家的地位&#xff0c;朱憙极力发展理学。 理学又叫道学。北有孔子&#xff0c;南有朱子。朱憙是理学集大成者&#xff0c;被称为朱子。理学…

STM32的GPIO初始化配置-学习笔记

简介&#xff1a; 由于刚开始没有学懂GPIO的配置原理&#xff0c;导致后面学习其它外设的时候总是产生阻碍&#xff0c;因为其它外设要使用前&#xff0c;大部分都要配置GPIO的初始化&#xff0c;因此这几天重新学习了一遍GPIO的配置&#xff0c;记录如下。 首先我们要知道芯片…

基于支持向量机SVM的点火电流预测

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 完整代码和数据下载链接:基于支持向量机SVM的点火电流预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88947558 SVM应用实例,基…

.Net Core 中间件验签

文章目录 为什么是用中间件而不是筛选器&#xff1f;代码实现技术要点context.Request.EnableBuffering()指针问题 小结 为什么是用中间件而不是筛选器&#xff1f; 为什么要用中间件验签&#xff0c;而不是筛选器去验签? 1、根据上图我们可以看到&#xff0c;中间件在筛选器之…

【Rockchip android7.1 平台rtl8821cs wifi移植调试】

Rockchip 平台rtl8821cs wifi移植调试 问题描述解决方法 郑重声明:本人原创博文&#xff0c;都是实战&#xff0c;均经过实际项目验证出货的 转载请标明出处:攻城狮2015 Platform: Rockchip rk3128 OS:Android 7.1.2 Kernel: 3.10 问题描述 客户需要在现在的板子上调一款RTL882…

前端的数据标记协议

文章目录 数据标记协议是什么数据标记协议的作用常见的数据标记协议Open Graph protocol 开放图谱协议基本元数据协议可选元数据结构化属性 —— 元数据的属性多个相同的元数据标签类型元数据的使用方法全局类型使用自定义类型使用对象类型使用歌曲对象类型视频对象类型文章对象…

算法打卡day15|二叉树篇04|110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

算法题 Leetcode 110.平衡二叉树 题目链接:110.平衡二叉树 大佬视频讲解&#xff1a;平衡二叉树视频讲解 个人思路 可以用递归法&#xff0c;计算左右子树的高度差&#xff0c;当超过1时就不为平衡二叉树了&#xff1b; 解法 回顾一下二叉树节点的深度与高度&#xff1b; …

软件测试知识面试题:白盒测试、黑盒测试、测试用例

文章目录 白盒测试1、白盒测试分两类2、白盒测试的四个原则3、白盒测试常用的7类测试 黑盒测试1、黑盒测试的优缺点2、黑盒测试的方法3、黑盒测试的原则 测试用例1、测试用例包含2、设计测试用例所需的文档资料3、采用白盒测试技术设计用例的目的4、采用黑盒测试技术设计用例的…