2.Seata 1.5.2 集成Springcloud-alibaba
一.Seata-server搭建已完成前提下
详见 Seata-server搭建
二.Springcloud 项目集成Seata
项目整体测试业务逻辑是创建订单后(为了演示分布式事务,不做前置库存校验),再去扣减库存。库存不够的时候,创建的订单信息数据也会回退。
2.1 springboot,springcloud,springboot,seata项目版本的版本管理pom配置
<!-- 统一依赖版本管理 --><properties><spring.boot.version>2.6.11</spring.boot.version><spring-cloud.version>2021.0.4</spring-cloud.version><spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version><seata.version>1.5.2</seata.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope><exclusions><exclusion><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><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></dependencies></dependencyManagement>
2.2 Porduct项目seata核心依赖和配置及代码和undolog表初始化
基本的web,持久化,数据库,数据配置中心,注册中心依赖此处略。
核心pom.xml如下:
<!--seata 分布式事务组件--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>
appliction.yml 核心配置如下:
# 端口
server:port: 8050servlet:context-path: /productApispring:application:name: dolphin-jinyi-productprofiles:active: devmvc:pathmatch:matching-strategy: ant_path_matchermain:allow-bean-definition-overriding: truecloud:nacos:# 注册中心discovery:server-addr: localhost:8848namespace: d6eccad6-681c-4133-b9ff-1abcd951297agroup: DOLPHIN_GROUP# 配置中心config:server-addr: localhost:8848file-extension: ymlgroup: DOLPHIN_GROUPnamespace: d6eccad6-681c-4133-b9ff-1abcd951297a# 这里可以配置多个共享配置文件shared-configs:- data-id: mysql-common.ymlgroup: DEFAULT_GROUPrefresh: true- data-id: redis-common.ymlgroup: DEFAULT_GROUPrefresh: true
logging:level:io:seata: INFO
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplseata:registry:# 配置seata的注册中心, 告诉seata client 怎么去访问seata server(TC)type: nacosnacos:server-addr: 127.0.0.1:8848 # seata server 所在的nacos服务地址application: seata-server # seata server 的服务名seata-server ,如果没有修改可以不配username: nacospassword: nacosgroup: DOLPHIN_GROUP # seata server 所在的组,默认就是SEATA_GROUP,没有改也可以不配namespace: d6eccad6-681c-4133-b9ff-1abcd951297aconfig:type: nacosnacos:server-addr: 127.0.0.1:8848username: nacospassword: nacosgroup: DOLPHIN_GROUP # seata server 所在的组,默认就是SEATA_GROUP,没有改也可以不配namespace: d6eccad6-681c-4133-b9ff-1abcd951297a#指定Nacos上的DataIddata-id: seata-server.ymltx-service-group: default_tx_group #这里每个服务都是对应不同的映射名,在配置中心可以看到 事务分组,必须和服务器配置一样service:vgroup-mapping:default_tx_group: defaultgrouplist:default: localhost:8091
java核心伪代码示例:
*/
@RestController
@RequestMapping("/product")
@Api(value = "商品Api", tags = {"商品Api"})
public class ProductController {@Resourceprivate IProductService productService;@PostMapping("updateProductStock")@ApiOperation(value = "updateProductStock-更新商品库存", notes = "updateProductStock-更新商品库存")public R updateProductStock(@RequestParam(value = "productId") Integer productId,@RequestParam(value = "num") Integer num) {productService.updateProductStock(productId,num);return R.ok();}
}
public interface IProductService extends IService<Product> {void updateProductStock(Integer productId, Integer num);
}
注:核心点在于根据产品id扣减库存的方法上需要分支事务 @Transactional(rollbackFor = Exception.class)注解。
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {@Override@Transactional(rollbackFor = Exception.class)public void updateProductStock(Integer productId, Integer num) {System.out.println("事务id---------------------->" + RootContext.getXID());LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<Product>().eq(Product::getProductId, productId).eq(Product::getStatus, 1).last("limit 1");Product product = this.getOne(queryWrapper);if (Objects.isNull(product)) {//商品不存在时抛异常throw new BizException(ResultCodeEnum.DATA_NOT_FOUND);}Integer stockNum = product.getStockNum() + num;if (stockNum < 0) {//库存不足时,抛异常throw new BizException(ResultCodeEnum.PRODUCT_STOCK_NOT_ENOUGH);}product.setStockNum(stockNum);this.updateById(product);}
}
在product项目对应的数据库中初始化undo_log表
CREATE TABLE `undo_log` (`branch_id` bigint(20) 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`),KEY `ix_log_created` (`log_created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AT transaction mode undo table';
2.3 Order项目seata核心依赖和配置及代码和undolog表初始化
基本的web,持久化,数据库,数据配置中心,注册中心依赖此处略。
核心pom.xml如下:
<!--seata 分布式事务组件--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>
appliction.yml 核心配置如下:
# 端口
server:port: 8010servlet:context-path: /orderApispring:application:name: dolphin-jinyi-orderprofiles:active: devmvc:pathmatch:matching-strategy: ant_path_matchermain:allow-bean-definition-overriding: truecloud:nacos:# 注册中心discovery:server-addr: localhost:8848namespace: d6eccad6-681c-4133-b9ff-1abcd951297agroup: DOLPHIN_GROUP# 配置中心config:server-addr: localhost:8848file-extension: ymlgroup: DOLPHIN_GROUPnamespace: d6eccad6-681c-4133-b9ff-1abcd951297a# 这里可以配置多个共享配置文件shared-configs:- data-id: redis-common.ymlgroup: DEFAULT_GROUPrefresh: truemybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
seata:registry:# 配置seata的注册中心, 告诉seata client 怎么去访问seata server(TC)type: nacosnacos:server-addr: 127.0.0.1:8848 # seata server 所在的nacos服务地址application: seata-server # seata server 的服务名seata-server ,如果没有修改可以不配username: nacospassword: nacosgroup: DOLPHIN_GROUP # seata server 所在的组,默认就是SEATA_GROUP,没有改也可以不配namespace: d6eccad6-681c-4133-b9ff-1abcd951297aconfig:type: nacosnacos:server-addr: 127.0.0.1:8848username: nacospassword: nacosgroup: DOLPHIN_GROUP # seata server 所在的组,默认就是SEATA_GROUP,没有改也可以不配namespace: d6eccad6-681c-4133-b9ff-1abcd951297a#指定Nacos上的DataIddata-id: seata-server.ymltx-service-group: default_tx_group #这里每个服务都是对应不同的映射名,在配置中心可以看到service:vgroup-mapping:default_tx_group: defaultgrouplist:default: localhost:8091
java核心伪代码示例:
@RestController
@RequestMapping("/order")
@Api(value = "订单Api", tags = {"订单Api"})
public class OrderController {@Resourceprivate IOrderService orderService;@ApiOperation(value = "createOrder-创建订单", notes = "createOrder-创建订单")@PostMapping("/createOrder")public R<Long> createOrder(@RequestBody @Validated OrderCreateDTO orderCreateDTO) {Long orderNo = orderService.createOrder(orderCreateDTO);return R.ok(orderNo);}
}
public interface IOrderService extends IService<Order> {Long createOrder(OrderCreateDTO orderCreateDTO);
}
注:核心注解 @GlobalTransactional
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {@Resourceprivate ProductServiceFeignClient productServiceFeignClient;public Long createOrderNo() {return IdUtil.getSnowflakeNextId();}@Override@GlobalTransactionalpublic Long createOrder(OrderCreateDTO orderCreateDTO) {System.out.println("事务id---------------------->" + RootContext.getXID());Order order = new Order();BeanUtil.copyProperties(orderCreateDTO, order);order.setOrderNo(this.createOrderNo());//创建订单this.insertOrder(order);//通过feign调用商品服务扣减库存productServiceFeignClient.updateProductStock(order.getProductId(), -1);return order.getOrderNo();}@Transactional(rollbackFor = Exception.class)public void insertOrder(Order order) {System.out.println("事务id A---------------------->" + RootContext.getXID());boolean save = this.save(order);if (!save) {throw new BizException(ResultCodeEnum.SYSTEM_EXECUTION_ERROR);}}}
在order项目对应的数据库中初始化undo_log表
CREATE TABLE `undo_log` (`branch_id` bigint(20) 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`),KEY `ix_log_created` (`log_created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AT transaction mode undo table';
三.设计到的nacos中的seata-server.yml等配置
注意上面项目的yml配置中的namespace,groupId,data-id 保持和nacos一直

seata-server.yml
service:vgroupMapping:default_tx_group: default
四 测试
测试时,保证seata-server order product 服务都已经启动。
现在库存有一个,没有订单信息数据。


4.1 第一次下单

商品表库存被扣减,创建订单成功


现在库存为0.第二次下单

订单没有新增,库存也没有扣减。分布式事务测试ok


相关文章:
2.Seata 1.5.2 集成Springcloud-alibaba
一.Seata-server搭建已完成前提下 详见 Seata-server搭建 二.Springcloud 项目集成Seata 项目整体测试业务逻辑是创建订单后(为了演示分布式事务,不做前置库存校验),再去扣减库存。库存不够的时候,创建的订单信息数…...
python 图像绘制问题: 使用turtle库绘制蟒蛇
turtle (海龟)库是turtle绘图体系的python实现。 1969年诞生,主要用于程序设计入门。 import turtle turtle.setup(650, 350, 200, 200) # 设置窗体(宽,高,窗体左上角x坐标,y坐标) turtl…...
大模型分布式训练并行技术(七)-自动并行
近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此,我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群&a…...
网络安全等级保护 | 规范企业网络系统安全使用 | 天锐股份助力等保制度落地
在当今数字化高速发展的时代,网络安全对于企业的重要性日益凸显。而近年来,数据泄露、网络攻击等安全事件频发,给企业和个人带来了前所未有的挑战。在这一背景下,网络安全等级保护制度(简称“等保”)作为国…...
Springboot使用redis,以及解决redis缓存穿透,击穿,雪崩等问题
1.Redis面试题-缓存穿透,缓存击穿,缓存雪崩 1 穿透: 两边都不存在(皇帝的新装) (返回空值)(互斥锁)(黑名单) (布隆过滤器) 2 击穿:一个或多个热…...
pve 命令开启关闭虚拟机
命令 #查看集群资源状况 #pvesh get /cluster/resources #取得虚拟机当前状态 #pvesh get /nodes/<节点id>/qemu/<虚拟机id>/status/current #pvesh get /nodes/www/qemu/107/status/current#关闭虚拟机 #pvesh create /nodes/<节点id>/qemu/<虚拟机id&…...
【达梦数据库】临时表的使用测试
目录 背景问题复现问题原因解决方法 背景 用户在使用临时表的过程中,执行commit提交命令之后,临时表的数据被清空,无法被接下来的存储过程复用。 问题复现 -----------------------------提交删除行----------------------------- --创建临…...
【GUI设计】基于Matlab的图像去噪GUI系统(8),matlab实现
博主简介: 如需获取设计的完整源代码或者有matlab图像代码项目需求/合作,可联系主页个人简介提供的联系方式或者文末的二维码。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Matlab的图像去噪GUI系统&am…...
【计算机科学导论】
计算机科学的本质就是解决问题,我们计算机由输入设备,处理设备和输出设备组成。 处理设备看做一个大黑盒,目的就是接收处理数据,然后发送到输出设备。计算机中存储数据就是2进制,0和1,0代表关,…...
【C++】I/O流的使用介绍
文章目录 什么是 I/O 流?C I/O 流的基本类型常用的 I/O 操作1. 标准输入输出2. 文件输入输出3. 字符串流 什么是 I/O 流? 在 C 中,I/O 流是数据的输入和输出通道。流的本质是一个字节序列,提供了抽象的方式来读写数据。C 使用流对…...
深度学习:(八)深层神经网络参数与流程
深层神经网络 符号规定 L L L :表示神经网络的层数; l l l :表示第几层; n [ l ] n^{[~l~]} n[ l ] :表示第 l l l 层的节点数; a [ l ] a^{[~l~]} a[ l ] :表示第 l l l 层中的激活函数&…...
`pattern = r“(\d+)(CNY|JPY|HKD|EUR|GBP|fen|cents|sen|eurocents|pence)“
pattern r"(\d)(CNY|JPY|HKD|EUR|GBP|fen|cents|sen|eurocents|pence)" 是一个正则表达式,用于匹配特定格式的字符串。 正则表达式解析 整体结构: r"...":前缀 r 表示这是一个原始字符串(Raw String&#x…...
宝塔面板部署雷池社区版教程
宝塔面板部署雷池社区版教程 简单介绍一下宝塔面板,安全高效的服务器运维面板,使用宝塔面板的人非常多 在网站管理上,许多用户都是通过宝塔面板进行管理,宝塔面板的Nginx默认监听端口为80和443,这就导致共存部署时雷池…...
【击败100%】258. 各位相加
首次出现,代码用时击败了100%的用户,开心~ 题目 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。 示例 1: 输入: num 38 输出: 2 解释: 各位相加的过程为: 38 --> 3 8 -->…...
【alist】宝塔面板docker里的alist默认admin无法登录
宝塔docker安装完alist,根据页面的提示账号密码死活登录不上,提示密码有问题 页面提示: 数据存储目录 /www/dk_project/dk_app/dk_alist 使用说明请参考: >使用教程 默认账号密码(admin/admin) 首次登录后点击个人…...
【击败100%】1281. 整数的各位积和之差
击败了100%的用户,开心~ 题目 给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。 示例 1: 输入:n 234 输出:15 解释: 各位数之积 2 * 3 * 4 24 各位数之和 2 3 4 …...
Flink基本概念和算子使用
基础概念 Flink是一个框架和分布式处理引擎,用于对无界数据流和有界数据流进行有状态计算,它的核心目标是“数据流上的有状态计算”。 有界流和无界流 有界流:具有明确的开始和结束时间,数据量有限。适合使用批处理技术…...
Kafka 3.0.0集群部署教程
1、集群规划 主机名 ip地址 node.id process.roles kafka1 192.168.0.29 1 broker,controller Kafka2 192.168.0.30 2 broker,controller Kafka3 192.168.0.31 3 broker,controller 2、将kafka包上传以上节点/app目录下 mkdir /app 3、解压kafka包 所有节点 …...
昇思MindSpore进阶教程-格式转换
大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 MindSpore中可以把用于训练网络模型的数据…...
搜索软件 Everything 的安装与使用教程
一、Everything简介 适用于 Windows 的免费搜索工具 Everything 是 Windows 的即时搜索引擎。发现、整理并轻松访问文件和文件夹,一切尽在指尖! PS:Everything无法对文件内容进行搜索,只能根据文件名和路径进行搜索 二、Everyt…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...
