当前位置: 首页 > news >正文

【分布式事务AT模式 SpringCloud集成Seata框架】分布式事务框架Seata详细讲解

前言

上篇文章我们讲述了如何启动seata的本地服务,并且注册到nacos使用,这篇文章将在SpringCloud中整合Seata框架

上篇文章传送门:https://blog.csdn.net/Syals/article/details/130102851?spm=1001.2014.3001.5501

本篇主要内容:@GlobalTransactional注解

  • @GlobalTransactional是Seata框架提供的注解,用于开启一个全局事务。当一个方法被标记为@GlobalTransactional时,Seata框架会自动创建一个全局事务,并将该方法的执行视为整个事务的一个参与者。

  • 在使用@GlobalTransactional注解时,需要在Seata Server中配置好相应的事务组,并使用相同的事务组ID和事务模式。同时,所有参与该全局事务的服务都需要使用相同的事务组ID和事务模式,并在业务代码中使用@Transactional注解开启本地事务。

  • 当全局事务中的任何一个本地事务发生异常时,Seata框架会回滚整个全局事务,保证数据的一致性。同时,Seata框架还提供了一系列的扩展点和机制,可以自定义全局事务的创建、提交和回滚过程,以满足不同场景的需求。

  • 使用@GlobalTransactional注解可以简化分布式事务的管理和操作,提高开发效率和数据一致性。

版本

版本号
jdk1.8
SpringBoot2.3.12.RELEASE
SpringCloud2.2.7.RELEASE
SpringCloudVersionHoxton.SR12

准备工作

  • 创建一个新的数据库seata-test,创建数据库表it_orderit_stockundo_log
    其中it_order是我们的订单表,it_stock为库存表,undo_log则为seata框架要求的事务日志表,在你每个要操作事务的数据库中都要有一个undo_log表

  • 这里的话数据表随便也可以,我现在就按演示的数据表来进行操作,但是undo_log表是固定的

undo_log表:

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (`id` bigint(0) NOT NULL AUTO_INCREMENT,`branch_id` bigint(0) NOT NULL,`xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,`context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(0) NOT NULL,`log_created` datetime(0) NOT NULL,`log_modified` datetime(0) NOT NULL,`ext` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

订单和库存表:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for it_order
-- ----------------------------
DROP TABLE IF EXISTS `it_order`;
CREATE TABLE `it_order`  (`id` bigint(0) NOT NULL AUTO_INCREMENT,`order_name` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,`order_status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for it_stock
-- ----------------------------
DROP TABLE IF EXISTS `it_stock`;
CREATE TABLE `it_stock`  (`id` bigint(0) NOT NULL AUTO_INCREMENT,`order_id` bigint(0) NULL DEFAULT NULL,`repertory` int(0) NULL DEFAULT NULL COMMENT '库存',`sales` int(0) NULL DEFAULT NULL COMMENT '销量',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;

工程结构图

在这里插入图片描述

依赖项说明

父级pom.xml

	<properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><java.version>1.8</java.version><spring.cloud.alibaba.version>2.2.7.RELEASE</spring.cloud.alibaba.version><spring.boot.version>2.3.12.RELEASE</spring.boot.version><spring.cloud.version>Hoxton.SR12</spring.cloud.version></properties><dependencies><!--SpringBoot基本场景启动--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!--SpringBoot 测试的场景启动--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><!--Spring Cloud alibaba的版本管理, 通过dependency完成继承--><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring.cloud.alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!--SpringBoot的版本管理--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency><!--Spring Cloud的版本管理--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

2 子级别pom.xml

一些常用的依赖项,例如mysql的驱动、web启动器、Druid、Mybaits框架等等。

3 孙级别pom.xml

order和stock的pom文件都是这三个

	<dependencies><!--nacos-服务注册发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--seata的依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency><!--1. openfeign依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies>

先来配置Order模块的配置文件

stock服务的配置文件我们就不在展示了,将下面配置文件的端口号改为8222,application.name改为seata-stock即可,其他的都是相同的。

server:port: 8111
spring:
#===============数据库连接=============datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/seata-test?characterEncoding=utf8&useSSL=false&serverTimezone=UTCdriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourceapplication:name: seata-order#order的服务名称cloud:#==============nacos的地址===============nacos:discovery:server-addr: 127.0.0.1:8848username: nacospassword: nacos
seata:
#==============seata的nacos配置=================registry:type: nacos#这里的type等同于registry.conf文件的mode = "nacos"nacos:server-addr: 127.0.0.1:8848 #seata所在的nacos服务地址username: nacospassword: nacosconfig:type: nacosnacos:server-addr: 127.0.0.1:8848username: nacospassword: nacos#这里要注意,这是我们在配置config.txt文件中讲述的service.vgroupMapping.后面的自定义名称#要跟你在上传配置文件中的组名称一致tx-service-group: my_tx_group
mybatis:mapper-locations: classpath:mapper/*.xmltypeAliasesPackage: com.it.entityconfiguration:mapUnderscoreToCamelCase: true

Fegin客户端的配置(Order服务需要,Stock不需要)

1 启动类上加上@EnableFeignClients注解
2 创建fegin包,并创建一个新的接口,StockService

//value的值是要调用的服务名称,path是接口前缀路径
@FeignClient(value = "seata-stock", path = "/stock/")
public interface StockService {//这个方法是修改库存方法@RequestMapping("updateStockByOrderId")public String updateStockByOrderId(@RequestParam("orderId") Long orderId);
}

Order服务的Controller

@RestController
@RequestMapping("/order/")
public class SeataOrderController {@Resourceprivate ItOrderService orderService;@RequestMapping("saveOrder")public String saveOrder() {return orderService.saveOrder();}
}

Order服务的ServiceImpl

@Service
public class ItOrderServiceImpl extends ServiceImpl<ItOrderMapper, ItOrder> implements ItOrderService {@Resourceprivate ItOrderMapper orderMapper;@Resourceprivate StockService stockService;@GlobalTransactional@Overridepublic String saveOrder() {ItOrder order = new ItOrder();order.setOrderName("技嘉主板");order.setOrderStatus("2");orderMapper.insert(order);order.setId(1L);stockService.updateStockByOrderId(order.getId());int i = 1 / 0;//故意报错return "执行完毕!";}
}

Stock服务的Controller

@RestController
@RequestMapping("/stock/")
public class SeataStockController {@Resourceprivate ItStockService stockService;@RequestMapping("updateStockByOrderId")public void updateStockByOrderId(Long orderId) {stockService.updateStockByOrderId(orderId);}
}

Stock服务的ServiceImpl

@Service
public class ItStockServiceImpl extends ServiceImpl<ItStockMapper, ItStock> implements ItStockService {@Resourceprivate ItStockMapper stockMapper;@Overridepublic void updateStockByOrderId(Long orderId) {ItStock stock = stockMapper.selectOne(new QueryWrapper<ItStock>().eq("order_id", orderId));stock.setRepertory(stock.getRepertory() - 1);stock.setSales(stock.getSales() + 1);stockMapper.updateById(stock);}
}

代码分析

我们可以看到在order服务中,我们在方法上标记了@GlobalTransactional注解,我们执行完插入语句然后远程调用修改库存服务,调用玩库存服务后故意抛出异常来测试两个服务之间是否都可以正常回滚操作

结束

最后的运行结果我就不在这里演示了,如果出现了@GlobalTransactional注解失效的问题那么有可能是以下原因:

  • Seata Server配置问题:如果Seata Server没有正确配置,包括事务组ID、事务模式等信息,那么使用@GlobalTransactional注解时就会失效。
  • 分布式事务管理器未启动:如果Seata Server未启动或者连接不上,那么使用@GlobalTransactional注解时也会失效。
  • 分布式事务传播机制问题:在分布式事务的调用链路中,每个服务都需要正确设置事务的传播机制,即在业务代码中使用@Transactional注解开启本地事务,同时在远程调用时正确传递事务上下文。如果其中任何一个服务未正确设置事务传播机制,那么@GlobalTransactional注解就会失效。
  • 事务模式不匹配:@GlobalTransactional注解的事务模式必须与Seata Server中配置的事务模式匹配,否则就会失效。如果Seata Server中配置的是AT模式,那么业务代码中使用的就必

总结

seata最难的地方是在于如何配置它,当搞清楚他的配置文件,使用它只需要一个注解即可,跟Spring提供的本地事务注解一样。
今天就分享到这里,拜拜啦!

相关文章:

【分布式事务AT模式 SpringCloud集成Seata框架】分布式事务框架Seata详细讲解

前言 上篇文章我们讲述了如何启动seata的本地服务&#xff0c;并且注册到nacos使用&#xff0c;这篇文章将在SpringCloud中整合Seata框架 上篇文章传送门&#xff1a;https://blog.csdn.net/Syals/article/details/130102851?spm1001.2014.3001.5501 本篇主要内容&#xff…...

系统集成项目管理工程师软考第三章习题(每天更新)

第一章指路&#xff1a;系统集成项目管理工程师软考第一章习题&#xff08;已完结&#xff09;_程序猿幼苗的博客-CSDN博客 第二章指路&#xff1a;系统集成项目管理工程师软考第二章习题&#xff08;已完结&#xff09;_程序猿幼苗的博客-CSDN博客 第3章信息系统集成专业技术…...

FIFO的工作原理及其设计

1.简介 FIFO( First Input First Output)简单说就是指先进先出。FIFO存储器是一个先入先出的双口缓冲器&#xff0c;即第一个进入其内的数据第一个被移出&#xff0c;其中一个口是存储器的输入口&#xff0c;另一个口是存储器的输出口。 对于单片FIFO来说&#xff0c;主要有两种…...

「UG/NX」Block UI 通过浏览器选择文件File Selection with Browse

目录 控件说明界面效果公有属性对话框标题 DialogLabel(仅创建)控件灰显 Enable分组 Group(仅创建)控件显隐 Show控件标题 Label国籍文本 AllowInternationalTextInput(仅创建)显示密文 IsPassword(仅创建)本地化 Localize(仅创建)保存值 RetainValue属性界面代码实现…...

面试官:如何搭建Prometheus和Grafana对业务指标进行监控?

Prometheus和Grafana都是非常流行的开源监控工具&#xff0c;可以协同使用来实现对各种应用程序、系统、网络和服务器等的监视和分析。 下面对Prometheus和Grafana进行简要介绍&#xff1a; Prometheus Prometheus是一款开源、云原生的系统和服务监控工具&#xff0c;它采用p…...

SQL Server 创建登录账号、创建用户名并为数据库赋予db_owner权限

服务器级的固定角色及其权限 sysadminsysadmin 固定服务器角色成员可以在服务器执行任何操作serveradminserveradmin 固定服务器角色的成员可以更该服务器范围的配置选项和关闭服务器sercurityadmin sercurityadmin 固定服务器角色的成员管理登录名及其属性,他们可以grant、de…...

离散数学_第二章:基本结构:集合、函数、序列、求和和矩阵(1)

集合与函数2.1 集合 2.1.1 集合的基本概念 2.1.2 集合的表示方法 2.1.3 文氏图 2.1.4 证明集合相等 2.1.5 集合的大小 ——基 2.1.6 幂集 2.1.7 集族、指标集 2.1.8 笛卡尔积 2.1.9 容斥原理2.1 集合 2.1.1 集合的基本概念 定义1&#xff1a;集合 是不同对象的一个无序的聚…...

ChatGPT想干掉开发人员,做梦去吧

很多人都发现ChatGPT可以做一些代码相关的工作&#xff0c;不仅可以写一些基础的类似python、java、js的代码段&#xff0c;还可以做一定量的调优&#xff0c;于是就开始担忧起来&#xff0c;到哪天我的开发工作会不会被ChatGPT这个工具给取代了&#xff1f; 目录 1. ChatGPT…...

尚硅谷大数据技术Hadoop教程-笔记04【Hadoop-MapReduce】

视频地址&#xff1a;尚硅谷大数据Hadoop教程&#xff08;Hadoop 3.x安装搭建到集群调优&#xff09; 尚硅谷大数据技术Hadoop教程-笔记01【大数据概论】尚硅谷大数据技术Hadoop教程-笔记02【Hadoop-入门】尚硅谷大数据技术Hadoop教程-笔记03【Hadoop-HDFS】尚硅谷大数据技术Ha…...

Linux信号sigaction / signal

Linux信号sigaction / signal 文章目录Linux信号sigaction / signal目的函数原型struct sigaction信号枚举值ISO C99 signals.Historical signals specified by POSIX.New(er) POSIX signals (1003.1-2008, 1003.1-2013).Nonstandard signals found in all modern POSIX system…...

坦克大战第一阶段代码

package tanke.game;import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Vector;//为了监听键盘事件&#xff0c;实现keylistener public class mypanel extends JPanel implements KeyListener …...

博客系统前端实现

目录 1.预期效果 2.实现博客列表页 3.实现博客正文页 4.实现博客登录页 5.实现博客编辑页面 1.预期效果 对前端html,css,js有大致的了解后,现在我们实现了一个博客系统的前端页面.一共分为四个页面没分别是:登陆页面,博客列表页,博客正文页,博客编辑页 我们看下四个界面…...

ChatGPT技术原理、研究框架,应用实践及发展趋势(附166份报告)

​ 一、AI框架重要性日益突显&#xff0c;框架技术发展进入繁荣期&#xff0c;国内AI框架技术加速发展&#xff1a; 1、AI框架作为衔接数据和模型的重要桥梁&#xff0c;发展进入繁荣期&#xff0c;国内外框架功能及性能加速迭代&#xff1b; 2、Pytorch、Tensorflow占据AI框…...

【屏幕自适应页面适配问题】CSS的@media,为了适应1440×900的屏幕,使用@media解决问题

文章目录bug修改实例CSS3 media 查询CSS 多媒体查询&#xff0c;适配各种设备尺寸bug修改实例 <template><div id"deptAllDown" style"height: 400px;width:880px"/> </template>为了适应1440900的屏幕&#xff0c;使用media解决问题 …...

一篇文章理解堆栈溢出

一篇文章理解堆栈溢出引言栈溢出ret2text答案ret2shellcode答案ret2syscall答案栈迁移答案堆溢出 unlink - UAF堆结构小提示向前合并/向后合并堆溢出题答案引言 让新手快速理解堆栈溢出&#xff0c;尽可能写的简单一些。 栈溢出 代码执行到进入函数之前都会记录返回地址到SP…...

优化模型验证关键代码27:多旅行商问题的变体-多起点单目的地问题和多汉密尔顿路径问题

目录 1 多起点单目的地问题(Multiple departures single destination mTSP) 1.1 符号列表 1.2 数学模型 1.4 解的可视化结果...

快速搭建第一个SpringCloud程序

目录 1、Spring Boot项目脚手架快速搭建 1.1 生成工程基本配置 1.2 生成工程。 1.3 导入开发工具&#xff08;此处为Idea&#xff09; 1.4 运行代码 1.5 验证是否能访问 2、Spring Cloud环境搭建 2.1 版本匹配问题 2.2 Spring Cloud环境测试 3、引入Eureka Server 3…...

【离散数学】图论

1、有n个点没有边 零图 2、有1个点没有边 平凡图 3、含有平行边的图 多重图 4、简单图 不含有平行边和自回环的图 5、任意两个结点之间都有边 完全图 6、环贡献 两度 7、所有顶点的度数之和等于边数的两倍 8、在有向图中所有顶点的出度之和 或者 入度之和 等于边数 9、度数为…...

代码随想录算法训练营第三十七天-贪心算法6| 738.单调递增的数字 968.监控二叉树 总结

738.单调递增的数字 贪心算法 题目要求小于等于N的最大单调递增的整数&#xff0c;那么拿一个两位的数字来举例。 例如&#xff1a;98&#xff0c;一旦出现strNum[i - 1] > strNum[i]的情况&#xff08;非单调递增&#xff09;&#xff0c;首先想让strNum[i - 1]--&#…...

【Linux】线程中的互斥锁、条件变量、信号量(数据安全问题、生产消费模型、阻塞队列和环形队列的实现)

文章目录1、线程互斥1.1 线程间频繁切换导致的问题1.2 使用互斥锁1.3 互斥锁的原理1.4 线程中的数据安全问题2、线程同步之条件变量2.1 生产消费模型2.2 条件变量概念和调用函数2.3 阻塞队列的实现3、线程同步之信号量3.1 理解信号量3.2 信号量接口3.3 环形队列的实现4、小结1、…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...