微服务SpringCloud分布式事务之Seata

视频教程:https://www.bilibili.com/video/BV16P63Y3ESq

效果演示

准备的微服务项目调用的链路如下:
在这里插入图片描述

文字描述:

  • gateway模块接收到请求,并发送到order订单模块
  • order订单模块接收到请求,新增一个订单数据后发送一个请求到pay支付模块
  • pay支付模块接收到请求,发送一个模块到account账户模块扣减余额并新增一条支付数据
  • account账户模块接收到请求,扣减账户余额

当我未标记 @GlobalTransactional 注解的时候,如图:
在这里插入图片描述

在这种情况下很理所应当的报错:
在这里插入图片描述

但是我成功的创建了支付信息:
在这里插入图片描述

且成功的扣减了余额:
在这里插入图片描述

只有订单模块的事务时成功的:
在这里插入图片描述

当我修改为使用Seata的分布式事务注解 @GlobalTransactional
在这里插入图片描述

同样发生了错误:
在这里插入图片描述

余额没有扣减:
在这里插入图片描述

没有新增订单信息:
在这里插入图片描述

也没有形成支付信息:
在这里插入图片描述

这证明了分布式事务Seata搭建成功,接下来我们一个一个步骤搭建一下这个框架。

项目准备

之前我有写过一篇关于SpringCloud整合Micrometer做链路追踪的文章,这篇文章当中准备了一个项目。可以使用下面两个连接下载整合了Micrometer但未整合Seata的项目代码(任选一个即可):

  • zip压缩包:https://github.com/xiaohh-me/xiaohh-cloud-micrometer/archive/refs/tags/v1.1.0.zip
  • tar.gz压缩包:https://github.com/xiaohh-me/xiaohh-cloud-micrometer/archive/refs/tags/v1.1.0.tar.gz

也可以选择未整合Micrometer的源代码(任选一个即可):

  • zip压缩包:https://github.com/xiaohh-me/xiaohh-cloud-micrometer/archive/refs/tags/v1.0.0.zip
  • tar.gz压缩包:https://github.com/xiaohh-me/xiaohh-cloud-micrometer/archive/refs/tags/v1.0.0.tar.gz

整合了Seata做分布式事务的代码:

  • zip压缩包:https://github.com/xiaohh-me/xiaohh-cloud-micrometer/archive/refs/tags/v1.2.0.zip
  • tar.gz压缩包:https://github.com/xiaohh-me/xiaohh-cloud-micrometer/archive/refs/tags/v1.2.0.tar.gz

该项目所使用到的技术栈:

技术栈版本
SpringBoot3.2.12
SpringCloud2023.0.4
SpringCloudAlibaba2023.0.1.0
MyBatisStarter3.0.4

因为使用到了3.*版本的SpringBoot,所以你需要安装Java17或更高版本。

搭建Seata分布式事务

Seata的安装和运行

本次安装的Seata版本为 2.2.0 ,下载链接为:https://dist.apache.org/repos/dist/release/incubator/seata/2.2.0/apache-seata-2.2.0-incubating-bin.tar.gz。也可以使用下面这行命令下载:

curl -LO https://dist.apache.org/repos/dist/release/incubator/seata/2.2.0/apache-seata-2.2.0-incubating-bin.tar.gz

然后可以使用下面命令解压,当然在Windows下你也可以使用如360压缩等软件进行解压:

tar -zxvf apache-seata-2.2.0-incubating-bin.tar.gz

解压之后目录如图:
在这里插入图片描述

此次只需要关注到 seata-server 目录的内容即可,目录内容:
在这里插入图片描述

需要修改这个目录下 conf/application.yml 文件,文件内容(注意需要修改nacos注册中心和配置中心,还有数据库配置):

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${log.home:${user.home}/logs/seata}extend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:# 控制台的用户名和密码username: seatapassword: seata
seata:config:# support: nacos, consul, apollo, zk, etcd3type: nacosnacos:# nacos 配置中心配置server-addr: 127.0.0.1:8848namespace: xiaohh-cloud-devgroup: SEATA_GROUPdata-id: seataServer.propertiesregistry:# support: nacos, eureka, redis, zk, consul, etcd3, sofatype: nacosnacos:# nacos 注册中心配置application: seata-serverserver-addr: 127.0.0.1:8848group: SEATA_GROUPnamespace: xiaohh-cloud-devcluster: defaultstore:# support: file 、 db 、 redis 、 raftmode: dbdb:# 数据库配置datasource: druiddb-type: mysqldriver-class-name: com.mysql.jc.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/xiaohh_seata?rewriteBatchedStatements=trueuser: rootpassword: xiaohhmin-conn: 10max-conn: 100global-table: global_tablebranch-table: branch_tablelock-table: lock_tabledistributed-lock-table: distributed_lockvgroup-table: vgroup_tablequery-limit: 1000max-wait: 5000#  server:#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000csrf-ignore-urls: /metadata/v1/**ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login,/version.json,/health,/error,/vgroup/v1/**

数据库建表语句可以通过这个地址获得:https://raw.githubusercontent.com/apache/incubator-seata/refs/heads/master/script/server/db/mysql.sql,也可以通过下面命令在已搭建好Seata分布式事务的代码仓库当中也有:
在这里插入图片描述

创建数据库,并执行这个脚本文件,现将命令行的目录移动到项目的sql当中,然后登录mysql并在mysql当中执行下面几行命令(可以改为自己的数据库名字哦):

drop database if exists `xiaohh_seata`;
create database `xiaohh_seata`;
use `xiaohh_seata`;
source seata_server.sql

执行如图:
在这里插入图片描述

然后确定你的seata配置文件没问题之后,先启动nacos,再启动seata。在确保nacos正常启动之后执行下面命令启动seata:

  • Windows:
bin/seata-server.bat
  • Mac/Linux:
./bin/seata-server.sh

Mac启动如图:
在这里插入图片描述

启动之后到对应的nacos命名空间下查看,可以看到seata已经以 seata-server 的名字注册到nacos注册中心中:
在这里插入图片描述

至此,seata安装和启动成功

修改项目代码

添加项目依赖

如果你的项目和我提供的项目一样,在聚合 pom.xml 或着项目的 pom.xml 当中添加了 spring-cloud-alibaba-dependencies 的依赖管理,如图:
在这里插入图片描述

则只需要在参与到分布式事务微服务的 pom.xml 中添加如下依赖即可:

<!-- Seata 分布式事务 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

添加如图:
在这里插入图片描述

修改bootstrap.yaml配置文件

需要修改参与到分布式事务微服务模块的 bootstrap.yaml 配置文件,告诉微服务模块seata的位置,添加的配置如下:

seata:# 数据源代理模式data-source-proxy-mode: ATregistry:nacos:# seata注册到nacos的配置server-addr: 127.0.0.1:8848namespace: xiaohh-cloud-devgroup: SEATA_GROUPapplication: seata-servertype: nacos# 采用默认的事务分组service:vgroup-mapping:default_tx_group: defaulttx-service-group: default_tx_group

添加如图:
在这里插入图片描述

为业务数据库新建表

AT模式分布式事务需要微服务模块的数据库当中有 undo_log 表,这个表存储了如果分布式事务失败了,应该如何回滚数据。这个表的建表语句在 https://raw.githubusercontent.com/apache/incubator-seata/refs/heads/master/script/client/at/db/mysql.sql 当中,也可以复制下面这行建表语句:

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(`branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',`xid`           VARCHAR(128) 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 = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

所有涉及到分布式事务的数据库都需要这张表:
在这里插入图片描述

修改事务注解

接下来来到需要分布式事务的 service 层方法,作者提供的项目该方法为 work.xiaohh.order.service.impl.OrderInfoServiceImpl#insertOrderInfo ,复制前面这段,来到 IDEA 当中双击 Shift 键,在搜索框当中输入即可查询到:
在这里插入图片描述

本方法还是使用Spring的事务注解 @Transactional,无法解决分布式事务问题:
在这里插入图片描述

需要修改为 @GlobalTransactional
在这里插入图片描述

然后在此方法的 return 语句前加上下面这行代码:

if (true) throw new RuntimeException("测试分布式事务失败异常");

添加如图:
在这里插入图片描述

测试分布式事务是否成功

接下来就可以测试分布式事务了,首先发送获取账户余额的请求,可以看到账户余额为10000:
在这里插入图片描述

然后请求分布式事务的接口,可以看到报错了:
在这里插入图片描述

然后再次请求获取账户余额接口,可以看到余额并没有被扣减:
在这里插入图片描述

也没有支付信息的产生:
在这里插入图片描述

可以确定分布式事务搭建成功!

修改报错消息

可以看到请求分布式事务接口时候,报错消息并不是代码中写的分布式消息,而是Seata返回的错误消息:
在这里插入图片描述

需要修改一下统一异常返回 RestControllerAdvice ,将 e.getMessage() 改为 e.getCause().getMessage() 即可,如图:
在这里插入图片描述

然后重启项目再次请求发现改为了代码当中写的Message:
在这里插入图片描述
好了,到此为止Seata分布式事务搭建成功

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pyhton知识分享-利用KNN算法实现手写数字识别

利用KNN算法实现手写数字识别 MNIST手写数字识别 是计算机视觉领域中 "hello world"级别的数据集 1999年发布&#xff0c;成为分类算法基准测试的基础随着新的机器学习技术的出现&#xff0c;MNIST仍然是研究人员和学习者的可靠资源。 本次案例中&#xff0c;我们的…

多点通信、流式域套接字

一、广播 1.1广播的发送端模型&#xff1a; #include<myhead.h>#define BEN_IP "192.168.191.129" #define BEN_PORT 8888#define PORT 6666int main(int argc, const char *argv[]) {int oldfd socket(AF_INET,SOCK_DGRAM,0);if(oldfd -1){perror("soc…

AMBA-APB

目录 1.APB 协议 2.APB信号列表 3.数据传输 3.1写传输&#xff08;2种&#xff09; 3.1.1 无等待状态的写传输 3.1.2有等待状态的写传输 3.2写选通信号 (PSTRB) 字节通道映射 3.3读传输&#xff08;2种&#xff09; 3.3.1 无等待状态的读传输 3.3.2有等待状态的读传…

linux自动化一键批量检查主机端口

1、准备 我们可以使用下面命令关闭一个端口 sudo iptables -A INPUT -p tcp --dport 端口号 -j DROP我关闭的是22端口&#xff0c;各位可以关其它的或者打开其它端口测试&#xff0c;谨慎关闭22端口&#xff01;不然就会像我下面一样握手超时&#x1f62d;&#x1f62d;&…

0055. shell命令--useradd

目录 55. shell命令--useradd 功能说明 语法格式 选项说明 选项 退出值 相关文件 /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/skel/ /etc/login.defs /etc/default/useradd 实践操作 注意事项 55. shell命令--useradd 功能说明 useradd 命令是 Lin…

UniApp 路由导航详解

一、引言 在当今的跨平台应用开发领域&#xff0c;UniApp 凭借其 “一套代码&#xff0c;多端运行” 的卓越特性&#xff0c;备受开发者青睐。而路由导航作为 UniApp 应用的关键环节&#xff0c;如同穿梭于各个页面场景的桥梁&#xff0c;直接关联着用户在应用内的操作体验。无…

【服务器】上传文件到服务器并训练深度学习模型下载服务器文件到本地

前言&#xff1a;本文教程为&#xff0c;上传文件到服务器并训练深度学习模型&#xff0c;与下载服务器文件到本地。演示指令输入&#xff0c;完整的上传文件到服务器&#xff0c;并训练模型过程&#xff1b;并演示完整的下载服务器文件到本地的过程。 本文使用的服务器为云服…

从零开始开发纯血鸿蒙应用之逻辑封装

从零开始开发纯血鸿蒙应用 一、前言二、逻辑封装的原则三、实现 FileUtil1、统一的存放位置2、文件的增删改查2.1、文件创建与文件保存2.2、文件读取2.2.1、读取内部文件2.2.2、读取外部文件 3、文件删除 四、总结 一、前言 应用的动态&#xff0c;借助 UI 响应完成&#xff0…

python读写文件的三种做法

对于文件操作&#xff0c;python提供了3种做法&#xff1a;open(), os.open() 和with open()语句。 1. open()函数&#xff1a;一般用于更高级的文件读写操作&#xff0c;即人能读懂的用法&#xff0c;如果是写入数据&#xff0c;可用传入字符串。 用法&#xff1a;open(path…

MySQL如何只取根据某列连续重复行的第一条记录

前言 MySQL如何只取根据某列连续重复行的第一条记录&#xff0c;条件&#xff1a;某列、连续、验重 建表准备 DROP TABLE IF EXISTS test; CREATE TABLE test (id bigint NOT NULL,time datetime NULL DEFAULT NULL,price int NULL DEFAULT NULL,PRIMARY KEY (id) USING BT…

Fetch处理大模型流式数据请求与解析

为什么有的大模型可以一次返回多个 data&#xff1f; Server-Sent Events (SSE)&#xff1a;允许服务器连续发送多个 data: 行&#xff0c;每个代表一个独立的数据块。 流式响应&#xff1a;大模型服务通常以流式响应方式返回数据&#xff0c;提高响应速度。 批量处理&#x…

MySQL 中存储金额数据一般使用什么数据类型

在 MySQL 中存储金额数据时&#xff0c;应该谨慎选择数据类型&#xff0c;以确保数据的精度和安全性。以下是几种常用的数据类型及其适用性&#xff1a; DECIMAL 类型&#xff1a; 描述&#xff1a;DECIMAL 类型是专门为存储精确的小数而设计的。它可以指定小数点前后的数字位数…

【数据结构】链表(1):单向链表和单向循环链表

链表 链表是一种经典的数据结构&#xff0c;它通过节点的指针将数据元素有序地链接在一起&#xff0c;在链表中&#xff0c;每个节点存储数据以及指向其他节点的指针&#xff08;或引用&#xff09;。链表具有动态性和灵活性的特点&#xff0c;适用于频繁插入、删除操作的场景…

离散数学考前一天

判断强连通&#xff0c;单向连通&#xff0c;弱连通&#xff1a; 求可达性矩阵P&#xff0c;P里面全是1&#xff0c;就是强连通 否则看P与P的转置矩阵&#xff0c;如果除了主对角线是0&#xff0c;其他全是1&#xff0c;就是单向连通 否则看A1&#xff1d;A与A的转置矩阵&am…

【服务器项目部署】⭐️将本地项目部署到服务器!

目录 &#x1f378;前言 &#x1f37b;一、服务器选择 &#x1f379; 二、服务器环境部署 2.1 java 环境部署 2.2 mysql 环境部署 &#x1f378;三、项目部署 3.1 静态页面调整 3.2 服务器端口开放 3.3 项目部署 ​ &#x1f379;四、测试 &#x1f378;前言 小伙伴们大家好…

chrome缓存机制以及验证缓存机制

一、Chrome 缓存机制 浏览器缓存机制旨在提高网页加载速度、减少服务器负载和节约带宽。Chrome 的缓存主要包括以下几种类型&#xff1a; 1. 强缓存 (Strong Cache) 无需向服务器发送请求即可使用缓存的资源。由 HTTP 响应头控制&#xff0c;包括&#xff1a; Expires&…

西门子DBX DBD DBB DBW的关系

DB10.DBD0 DB10.DBW0DB10.DBW2 DB10.DBB0DB10.DBB1DB10.DBB2DB10.DBB3 DB10.DBX0.00.7DB10.DBX1.01.7DB10.DBX2.02.7DB10.DBX3.03.7 使用之前需要在DB10中先定义&#xff0c;如果你仅在DB10中定义了一个DBD0&#xff0c;那么原则上你是可以使用上述所有地址的&#xff0c;但…

Android `android.graphics` 包深度解析:架构与设计模式

Android android.graphics 包深度解析:架构与设计模式 目录 引言android.graphics 包概述核心类与架构 CanvasPaintBitmapColorPathShaderMatrix设计模式在 android.graphics 中的应用 工厂模式装饰者模式策略模式享元模式高级图形处理技术 硬件加速离屏渲染自定义 View 中的…

Nginx的性能分析与调优简介

Nginx的性能分析与调优简介 一、Nginx的用途二、Nginx负载均衡策略介绍与调优三、其他调优方式简介四、Nginx的性能监控 一、Nginx的用途 ‌Nginx是一种高性能的HTTP和反向代理服务器&#xff0c;最初作为HTTP服务器开发&#xff0c;主要用于服务静态内容如HTML文件、图像、视…

vue2使用pdfjs-dist和jsPDF生成pdf文件

vue2使用pdfjs-dist和jsPDF生成pdf文件 1、安装依赖 npm install pdfjs-dist2.6.3472、引入依赖 import { jsPDF } from jspdf// 使用require方式导入pdfjs-dist v2.6.347&#xff0c;高版本报错&#xff08;import导入会报错&#xff1a;GlobalWorkerOptions undefined&…