Seata 2.x 系列【11】多数据源分布式事务

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

本系列Seata 版本 2.0.0

本系列Spring Boot 版本 3.2.0

本系列Spring Cloud 版本 2023.0.0

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

文章目录

    • 1. 概述
    • 2. 多数据源环境搭建
      • 2.1 数据库
      • 2.2 项目搭建
    • 3. Seata 集成
      • 3.1 undo_log 表
      • 3.2 引入依赖
      • 3.3 配置
      • 3.4 添加注解
      • 3.5 测试

1. 概述

在之前的案例中,我们在Spring Cloud微服务场景下使用Seata解决了分布式事务问题,在单体架构中,单个服务也可能存在跨库导致的分布式事务问题,例如下图中,因为分库导致下单请求需要连接多个数据库进行操作:
在这里插入图片描述

2. 多数据源环境搭建

这里使用MyBatis-Plus开发团队提供的多数据源框架dynamic-datasource,相关简介可参考官网。

2.1 数据库

使用的是Mysql 8.0.29,首先创建三个数据库:

  • seata_account:账户
  • seata_order:订单
  • seata_stock:库存

seata_account库插入t_account表:

CREATE TABLE `t_account` (`id` int NOT NULL AUTO_INCREMENT,`user_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`amount` double(14,2) DEFAULT '0.00',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;INSERT INTO t_account
(user_id, amount)
VALUES(1, 10000.00);

seata_order库插入t_order表:

CREATE TABLE `t_order` (`id` int NOT NULL AUTO_INCREMENT,`order_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`user_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`commodity_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`count` int DEFAULT '0',`amount` double(14,2) DEFAULT '0.00',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=64 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

seata_stock库插入t_stock表:

CREATE TABLE `t_stock` (`id` int NOT NULL AUTO_INCREMENT,`commodity_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,`count` int DEFAULT '0',PRIMARY KEY (`id`),UNIQUE KEY `commodity_code` (`commodity_code`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;INSERT INTO t_stock
(commodity_code, name, count)
VALUES('IPHONE', '苹果手机', 10000);

2.2 项目搭建

注意:这里省略了一些简单代码,完整代码请参考案例源码

项目技术栈:

  • JDK 17
  • Maven 3.6.3
  • Seata 2.0
  • Mybatis Plus 3.5.5
  • Dynamic Datasource 4.3.0
  • Spring Boot 3.2.0

使用Spring Initializr创建一个Spring Boot服务项目,引入相关依赖:

    <dependencies><!--Spring Boot Web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--工具--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.21</version></dependency><!--Mybatis Plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot3-starter</artifactId><version>4.3.0</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency></dependencies>

添加多数据源配置:

server:port: 9000
spring:application:name: dynamic-datasource-seata-demodatasource:dynamic:hikari:minimum-idle: 5idle-timeout: 30000maximum-pool-size: 20max-lifetime: 1800000connection-timeout: 50000primary: d_accountdatasource:d_account:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata_account?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=trueusername: rootpassword: 123456d_order:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata_order?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=trueusername: rootpassword: 123456d_stock:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata_stock?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=trueusername: rootpassword: 123456

各个Mapper接口添加DS注解:

@DS("d_account")
@DS("d_order")
@DS("d_stock")

BusinessService服务添加下单功能:

    public Object handleBusiness() {// 1. 业务请求数据BusinessDTO businessDTO =new BusinessDTO();businessDTO.setUserId("1"); // 下单用户businessDTO.setCount(1); // 数量businessDTO.setCommodityCode("IPHONE"); // 商品编号businessDTO.setAmount(new BigDecimal(1)); // 订单金额log.info("业务请求数据:"+ businessDTO);// 2. 扣减库存 CommodityDTO commodityDTO = new CommodityDTO();commodityDTO.setCommodityCode(businessDTO.getCommodityCode()); // 商品编号commodityDTO.setCount(businessDTO.getCount()); // 数量Object stock = stockService.decreaseStock(commodityDTO);log.info("调用库存服务:"+ stock);// 3. 创建订单OrderDTO orderDTO = new OrderDTO();orderDTO.setUserId(businessDTO.getUserId());orderDTO.setCommodityCode(businessDTO.getCommodityCode());orderDTO.setOrderCount(businessDTO.getCount());orderDTO.setOrderAmount(businessDTO.getAmount());OrderDTO response = orderService.createOrder(orderDTO);log.info("调用订单服务:"+ response);return orderDTO;}

3. Seata 集成

3.1 undo_log 表

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

-- seata_account.undo_log definitionCREATE TABLE `undo_log` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',`branch_id` bigint NOT NULL COMMENT '分支事务ID',`xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT '全局事务唯一标识',`context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT '上下文',`rollback_info` longblob NOT NULL COMMENT '回滚信息',`log_status` int NOT NULL COMMENT '状态,0正常,1全局已完成(防悬挂)',`log_created` datetime NOT NULL COMMENT '创建时间',`log_modified` datetime NOT NULL COMMENT '修改时间',PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='AT模式回滚日志表';

seata_accountseata_orderseata_stock库中,都新建undo_log表。

3.2 引入依赖

这里演示的是单机模式,所以不需要注册中心、配置中心,引入seata提供的Spring Boot启动包:

        <dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>2.0.0</version></dependency>

3.3 配置

application.yml中配置使用file作为注册中心、配置中心:

seata:# 配置中心config:type: filefile:name: file.conf# 注册中心registry:type: file

多数据源配置开启Seata,并设置事务模式:

  datasource:dynamic:seata: true # 启用Seataseata-mode: at # 事务模式,支持AT、XAhikari:minimum-idle: 5

resources目录下添加file.conf配置文件,内容如下:

transport {# tcp udt unix-domain-sockettype = "TCP"#NIO NATIVEserver = "NIO"#enable heartbeatheartbeat = true# the client batch send request enableenableClientBatchSendRequest = true#thread factory for nettythreadFactory {bossThreadPrefix = "NettyBoss"workerThreadPrefix = "NettyServerNIOWorker"serverExecutorThread-prefix = "NettyServerBizHandler"shareBossWorker = falseclientSelectorThreadPrefix = "NettyClientSelector"clientSelectorThreadSize = 1clientWorkerThreadPrefix = "NettyClientWorkerThread"# netty boss thread size,will not be used for UDTbossThreadSize = 1#auto default pin or 8workerThreadSize = "default"}shutdown {# when destroy server, wait secondswait = 3}serialization = "seata"compressor = "none"
}
service {#transaction service group mappingvgroupMapping.default_tx_group = "default"#only support when registry.type=file, please don't set multiple addressesdefault.grouplist = "127.0.0.1:8091"#degrade, current not supportenableDegrade = false#disable seatadisableGlobalTransaction = false
}client {rm {asyncCommitBufferLimit = 10000lock {retryInterval = 10retryTimes = 30retryPolicyBranchRollbackOnConflict = true}reportRetryCount = 5tableMetaCheckEnable = falsereportSuccessEnable = false}tm {commitRetryCount = 5rollbackRetryCount = 5}undo {dataValidation = truelogSerialization = "jackson"logTable = "undo_log"}log {exceptionRate = 100}
}

file.conf中需要注意配置TC地址:
在这里插入图片描述

3.4 添加注解

添加分布式事务注解@GlobalTransactional

    @GlobalTransactionalpublic Object handleBusiness() {//......}

3.5 测试

启动Seata、后台服务,查看日志,可以看到成功连接TC,并在AT模式下自动代理了数据源:
在这里插入图片描述
当发生业务异常时,可以看到多个RM都进行了回滚操作,查看数据库也发现数据一致,说明集成成功:
**在这里插入图片描述**

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

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

相关文章

SQLiteC/C++接口简介

快速跳转文章列表&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite——世界上部署最广泛的开源数据库&#xff08;简介&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍&#xff08;一&#xff09; 引言&#xff1a; 作为一种轻量级、嵌入式关系型数据库…

MAC M芯片 Anaconda安装

Anaconda安装 1.M芯片下载AnaConda 1.M芯片下载AnaConda https://www.anaconda.com/download 安装完成 conda的版本是24.1.2

Go语言中的make和new:内存分配与对象创建的巧妙之道

Go语言中的make和new&#xff1a;内存分配与对象创建的巧妙之道 Go语言作为一门简洁而强大的编程语言&#xff0c;提供了多种用于动态内存分配和对象创建的关键词。其中&#xff0c;make和new是两个常见且常被混淆的关键词。本文将深入讲解Go语言中make和new的区别&#xff0c;…

python来判断密码强弱-类

设计者&#xff1a;ISDF 版本&#xff1a;v1.0 日期&#xff1a;2019/4/3设计者&#xff1a;ISDF 版本&#xff1a;v2.0 日期&#xff1a;2024/4/3 class PasswordTool:密码工具类def __init__(self,password):#类的属性self.password passwordself.stregth_level 0def check…

考研C语言复习进阶(5)

目录 1. 为什么使用文件 2. 什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 3. 文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 4. 文件的顺序读写 ​编辑 ​编辑 4.1 对比一组函数&#xff1a; ​编辑 5. 文件的随机读写 5.1 fseek 5.2 ftell 5.3 rewind…

【C语言】linux内核pci_save_state

一、中文注释 //include\linux\pci.h /* 电源管理相关的例程 */ int pci_save_state(struct pci_dev *dev);//drivers\pci\pci.c /*** pci_save_state - 在挂起前保存PCI设备的配置空间* dev: - 我们正在处理的PCI设备*/ int pci_save_state(struct pci_dev *dev) {int i;/* X…

谷歌网络营销方案有几种?​

谷歌作为海外的头部工具&#xff0c;本身其实就有多种工具可以供你使用&#xff0c;在这里说说谷歌那些工具 Google My Business&#xff0c;对于小企业或者本地服务来说&#xff0c;把自己的业务信息优化并完善在Google My Business上是个不错的选择。这样当人们在附近搜索相…

微信小程序云开发教程——墨刀原型工具入门(表单组件)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

【NC223888】红色和紫色

题目 红色和紫色 博弈论&#xff0c;想得出来思路就简单&#xff0c;想不出来就难。一般使用猜测法。 思路 如果小红随意取一个格子涂色&#xff0c;那么小紫怎么涂色才是她的最优选择呢&#xff1f; 假设小紫只能选择小红涂色的格子的相邻格子或者是最近斜对角的一个格子涂色…

LeetCode 2684.矩阵中移动的最大次数:一列一列处理,只记能到哪行(BFS)

【LetMeFly】2684.矩阵中移动的最大次数&#xff1a;一列一列处理&#xff0c;只记能到哪行(BFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/ 给你一个下标从 0 开始、大小为 m x n 的矩阵 grid &#xff0c;矩阵由若干 正 整…

【漏洞复现】大华智慧园区综合管理平台SQL注入漏洞

Nx01 产品简介 大华智慧园区综合管理平台是一款综合管理平台&#xff0c;具备园区运营、资源调配和智能服务等功能。该平台旨在协助优化园区资源分配&#xff0c;满足多元化的管理需求&#xff0c;同时通过提供智能服务&#xff0c;增强使用体验。 Nx02 漏洞描述 大华智慧园区…

Halcon图像预处理、阈值分割

1、blob&#xff08;Binary Large Object&#xff09;是指二值图像中连通区域。 预处理通常包括一系列步骤&#xff0c;例如去噪、形态学操作、特征提取等。 read_image(Image,claudia) get_image_size(Image,Width,Height) dev_open_window_fit_size (0, 0, Width, Width, -1,…

如何在iPhone上恢复已删除的微信聊天记录?

你好&#xff0c;我前几天删除了微信聊天记录。有什么办法可以恢复iPhone上已删除的微信聊天记录吗&#xff1f; 有些人每次使用设备时都会遇到在 iPhone 上丢失消息的风险。特别是&#xff0c;由于多种因素&#xff0c;可能会丢失第三方数据&#xff0c;微信消息也是如此。微…

2024Vue高频面试题

前言: Vue 在前端开发领域拥有强劲的发展势头,以下是一些 Vue 的发展趋势: 1.持续增长的用户数量: Vue 作为一款轻量级、易学易用的前端框架,吸引了越来越多的开发者和企业选择使用。其活跃的社区和丰富的资源也促进了用户数量的不断增长。 2.生态系统不断丰富: 随着 V…

远超预期,特效吹爆!《武庚纪》:建议漫改都按这个标准来!

作为《武庚纪》动画党&#xff0c;听闻要改编成真人电视剧时&#xff0c;最害怕的无非五毛钱特效&#xff0c;流水线仙侠&#xff0c;无脑古偶。但在看过《烈焰》&#xff08;原名&#xff1a;武庚纪&#xff09;之后&#xff0c;不得不感叹一句&#xff1a;“倒也不用这么还原…

【计算机网络篇】计算机网络的性能指标

文章目录 &#x1f354;计算机网络的性能指标&#x1f5c3;️常见的计算机网络性能指标⭐速率⭐带宽⭐吞吐量⭐时延⭐时延带宽积⭐往返时间⭐利用率⭐丢包率 &#x1f50e;总结 &#x1f354;计算机网络的性能指标 计算机网络的性能指标被用来从不同方面度量计算机网络的性能 …

算法的渐进时间复杂度

T(n) = O(F(n)) T(n):Time 渐进时间复杂度 O:正比例关系 F(n):代码执行次数 只要代码执行的次数越来越多 所耗费的时间也就越来越高 常见的5种: O(n^2) O(n logn) O(n) O(logn) O(1):不管重复多少次1次也是这个时间,10次也是这个时间。 时间复杂度排序:由小到…

JAVA22 FFM实战之HelloWorld

前言 JDK22即将发布&#xff0c;Java Foreign Function & Memory API将会退出预览&#xff0c;是时候开始学习一波了。 FFM API介绍 FFM API由两大部分组成&#xff0c;一个是Foreign Function Interface&#xff0c;另一个是Memory API。前者是外部函数接口&#xff0c…

对模型性能进行评估(Machine Learning 研习十五)

在上一篇我们已然训练了一个用于对数字图像识别的模型&#xff0c;但我们目前还不知道该模型在识别数字图像效率如何&#xff1f;所以&#xff0c;本文将对该模型进行评估。 使用交叉验证衡量准确性 评估模型的一个好方法是使用交叉验证&#xff0c;让我们使用cross_val_score…

机器学习-04-分类算法-02贝叶斯算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法与贝叶斯算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程…