微服务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: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${log.home:${user.home}/logs/seata}
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash

console:
  user:
    # 控制台的用户名和密码
    username: seata
    password: seata
seata:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      # nacos 配置中心配置
      server-addr: 127.0.0.1:8848
      namespace: xiaohh-cloud-dev
      group: SEATA_GROUP
      data-id: seataServer.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      # nacos 注册中心配置
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: xiaohh-cloud-dev
      cluster: default
  store:
    # support: file 、 db 、 redis 、 raft
    mode: db
    db:
      # 数据库配置
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.jc.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/xiaohh_seata?rewriteBatchedStatements=true
      user: root
      password: xiaohh
      min-conn: 10
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      vgroup-table: vgroup_table
      query-limit: 1000
      max-wait: 5000
  #  server:
  #    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    csrf-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: AT
  registry:
    nacos:
      # seata注册到nacos的配置
      server-addr: 127.0.0.1:8848
      namespace: xiaohh-cloud-dev
      group: SEATA_GROUP
      application: seata-server
    type: nacos
  # 采用默认的事务分组
  service:
    vgroup-mapping:
      default_tx_group: default
  tx-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分布式事务搭建成功

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

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

相关文章

Solon 加入 GitCode:助力国产 Java 应用开发新飞跃

在当今数字化快速发展的时代&#xff0c;Java 应用开发框架不断演进&#xff0c;开发者们始终在寻找更快、更小、更简单的解决方案。近期&#xff0c;Solon 正式加入 GitCode&#xff0c;为广大 Java 开发者带来全新的开发体验&#xff0c;尤其是在国产应用开发进程中&#xff…

[实用指南]如何将视频从iPhone传输到iPad

概括 将视频从 iPhone 传输到 iPad 时遇到问题&#xff1f;您可能知道一种方法&#xff0c;但不知道如何操作。此外&#xff0c;您要传输的视频越大&#xff0c;完成任务就越困难。那么如何将视频从 iPhone 传输到 iPad&#xff0c;特别是当您需要发送大视频文件时&#xff1f…

【一起python】银行管理系统

文章目录 &#x1f4dd;计算机基础概念&#x1f320; 导入模块&#x1f320;定义input_card_info函数&#x1f320; 定义check_password函数&#x1f320;初始化用户字典和欢迎信息&#x1f309; 主循环&#x1f309;开户操作&#x1f309;查询操作&#x1f309;取款操作&#…

20241218-信息安全理论与技术复习题

20241218-信息安全理论与技术复习题 一、习题1 信息安全的基本属性是&#xff08;D )。 A、机密性 B、可用性 C、完整性 D、上面 3 项都是 “会话侦听和劫持技术” 是属于&#xff08;B&#xff09;的技术。 A、 密码分析还原 B、 协议漏洞渗透 C、 应用漏洞分析与渗透 D、 D…

音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件

一、错误的命令 通过FFmpeg命令可以将mp4文件转换为ps文件&#xff0c;PS文件中包含PS流数据。 由于PS流/PS文件对应的FFInputFormat结构为&#xff1a; const FFInputFormat ff_mpegps_demuxer {.p.name "mpeg",.p.long_name NULL_IF_CONFIG_SMALL…

Unity is running as administrator解决办法

每次打开Unity项目都会有这个弹窗 解决办法&#xff1a; 打开本地安全策略 - 安全选项 &#xff0c;把 用户账户控制&#xff1a;以管理员批准模式运行所有管理员 用户账户控制&#xff1a;用于内置管理员账户的管理员批准模式 改成已启用就行

活动预告 |【Part1】Microsoft Azure 在线技术公开课:数据基础知识

课程介绍 参加“Azure 在线技术公开课&#xff1a;数据基础知识”活动&#xff0c;了解有关云环境和数据服务中核心数据库概念的基础知识。通过本次免费的介绍性活动&#xff0c;你将提升在关系数据、非关系数据、大数据和分析方面的技能。 活动时间&#xff1a;01 月 07 日…

SQL-leetcode-183. 从不订购的客户

183. 从不订购的客户 Customers 表&#xff1a; -------------------- | Column Name | Type | -------------------- | id | int | | name | varchar | -------------------- 在 SQL 中&#xff0c;id 是该表的主键。 该表的每一行都表示客户的 ID 和名称。 Orders 表&#…

HTML5滑块(Slider)

HTML5 的滑块&#xff08;Slider&#xff09;控件允许用户通过拖动滑块来选择数值。以下是如何实现一个简单的滑块组件的详细说明。 HTML5 滑块组件 1. 基本结构 使用 <input type"range"> 元素可以创建一个滑块。下面是基本实现的代码示例&#xff1a; <…

报错:websocket注入为null,已解决!

错误截图 原因分析&#xff1a; WebSocket 在 Spring 框架中的注入问题是由其生命周期与 Spring 容器的作用域不一致引起的。spring管理的都是单例&#xff08;singleton&#xff09;&#xff0c;和 websocket &#xff08;多对象&#xff09;相冲突。如果你的WebSocket 处理类…

ClickHouse副本搭建

一. 副本概述 副本的目的主要是保障数据的高可用性&#xff0c;ClickHouse中的副本没有主从之分。所有的副本都是平等的。 副本写入流程&#xff1a; 二. 副本搭建 1. 实验环境 hadoop1(192.168.47.128) hadoop2(192.168.47.129)2. 修改配置文件 修改两台主机/etc/click…

ChatBI来啦!NBAI 正式上线 NL2SQL 功能

NebulaAI 现已正式上线 NL2SQL 功能&#xff0c;免费开放使用&#xff01; 什么是 NL2SQL&#xff1f;NL2SQL 即通过自然语言交互&#xff0c;用户可以轻松查询、分析和管理数据库中的数据&#xff08;ChatBI&#xff09;&#xff0c;从此摆脱传统复杂的数据库操作。 欢迎免费…

科技云报到:洞见2025年科技潮流,技术大融合开启“智算时代”

科技云报到原创。 随着2024年逐渐接近尾声&#xff0c;人们不禁开始展望即将到来的2025年。这一年&#xff0c;被众多科技界人士视为开启新纪元的关键节点。站在新的起点上&#xff0c;我们将亲眼目睹未来科技如何改变我们的世界。从人工智能到量子计算&#xff0c;从基因编辑…

【数据仓库】spark大数据处理框架

文章目录 概述架构spark 架构角色下载安装启动pyspark启动spark-sehll启动spark-sqlspark-submit经验 概述 Spark是一个性能优异的集群计算框架&#xff0c;广泛应用于大数据领域。类似Hadoop&#xff0c;但对Hadoop做了优化&#xff0c;计算任务的中间结果可以存储在内存中&a…

标准库以及HAL库——按键控制LED灯代码

按键控制LED本质还是控制GPIO,和点亮一个LED灯没什么区别 点亮一个LED灯&#xff1a;是直接控制输出引脚&#xff0c;GPIO初始化推挽输出即可 按键控制LED&#xff1a;是按键输入信号从而控制输出引脚&#xff0c;GPIO初始化推挽输出一个引脚以外还得加一个GPIO上拉输入 但是…

Rabbitmq追问2

分析rabbitmq 默认使用姿势是什么 direct fanout还是什么 public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException { this.send(exchange, routingKey, this.convertMessageIfNecessary(obje…

vue+js+Java在分页的el-table里实现上移、下移;置顶

这里写目录标题 一、上移、下移二、置顶 一、上移、下移 实现&#xff1a;上移到第一行后不能再上移&#xff0c;下移到最后一行不能下移&#xff0c;以及分页后能上移到前一页&#xff0c;下移能移到后一页&#xff1b;&#xff08;新增sort排序字段&#xff09; <el-tabl…

计算机因进程结束导致白屏

问题场景&#xff1a; 计算机卡顿利用&#xff08;右击计算机桌面底部任务栏->打开任务管理器->结束任务->或进程被意外结束导致白屏&#xff09; 问题描述 白屏 原因分析&#xff1a; 在结束进程时&#xff0c;导致 文件资源管理器 进程崩溃。 解决方案&#xf…

【YashanDB知识库】如何在备机节点上做备份和恢复

本文内容来自YashanDB官网&#xff0c;原文内容请见 https://www.yashandb.com/newsinfo/7817898.html?templateId1718516 问题现象 一主一备情况下&#xff0c;主机需要支持常规业务&#xff0c;为了不影响业务&#xff0c;在备机做备份恢复的场景。 问题的风险及影响 1、…

【Linux-多线程】线程互斥(锁和它的接口等)

一、线程互斥 我们把多个线程能够看到的资源叫做共享资源&#xff0c;我们对共享资源进行保护&#xff0c;就是互斥 1.多线程访问问题 【示例】见一见多线程访问问题&#xff0c;下面是一个抢票的代码&#xff0c;共计票数10000张&#xff0c;4个线程去抢 之前我们展示过封…