闲谭SpringBoot--ShardingSphere分布式事务探究

文章目录

  • 0. 背景
  • 1. 未分库分表时
  • 2. 仅分表时
  • 3. 分库分表时
    • 3.1 不涉及分库表
    • 3.2 涉及分库表,且分库表处于一个库
    • 3.3 涉及分库表,且分库表处于多个库
    • 3.4 涉及分库表,且运行中某库停机
  • 4. 小结

0. 背景

接上篇文章《闲谭SpringBoot–ShardingSphere分库分表探究》,我已经完成分库分表的项目搭建。

本篇探究在不同情况下,事务是否正常运作。

1. 未分库分表时

针对不分库的user表,故意抛出异常,看看能否回滚。

执行前:
在这里插入图片描述
执行代码:

     /**
     * 在未分库分表的情况下,可以正常回滚
     */
    @Transactional(rollbackFor = Exception.class)
    public int testWithNoDivide() throws Exception {
        UserDo user = new UserDo();
        user.setId("2");
        user.setName("testWithNoDivide");
        int re = userService.add(user);
        if (true) {
            throw new Exception("err");
        }
        return re;
    }

执行后,由于抛出异常,事务回滚,数据库中的内容并未改变。

测试通过。

2. 仅分表时

如果将log表按时间进行分表,我们看能否回滚。

首先验证只使用@Transactional(rollbackFor = Exception.class)能否回滚多个表:

	/**
     * 在仅分表的情况下,测试是否可以回滚
     */
    @Transactional(rollbackFor = Exception.class)
    public int testWithTableDivide() throws Exception {
        // 改用户
        UserDo user = new UserDo();
        user.setId("2");
        user.setName("testWithTableDivide");
        int reUser = userService.add(user);
        // 改日志
        LogDo log = new LogDo();
        log.setId("111");
        log.setTime("2025-01-01 11:11:11");
        log.setContent("testWithTableDivide");
        int reLog = logService.add(log);
        // 抛出异常
        if (true) {
            throw new Exception("err");
        }
        return reUser + reLog;
    }

通过验证,发现是可以正常回滚的,所以在仅分表不分库的情况下,使用@Transactional(rollbackFor = Exception.class)足矣。

3. 分库分表时

如果既分库、又分表,是否需要开启分布式事务呢?

我们分两步验证,首先验证不涉及分库的表时,其次验证涉及分库的表时。

3.1 不涉及分库表

此时对log分库分表,测试user是否能正常回滚:

	/**
     * 在未分库分表的情况下,可以正常回滚
     */
    @Transactional(rollbackFor = Exception.class)
    public int testWithNoDivide() throws Exception {
        UserDo user = new UserDo();
        user.setId("2");
        user.setName("testWithNoDivide");
        int re = userService.add(user);
        if (true) {
            throw new Exception("err");
        }
        return re;
    }

这个应该是没有悬念的,不涉及分库的表,没必要开启分布式事务。

3.2 涉及分库表,且分库表处于一个库

我们同时修改user表、log表,但是让user和log处于一个数据库ds0里面,测试能否回滚

  	/**
     * 涉及分库表,且分库表处于一个库
     */
    @Transactional(rollbackFor = Exception.class)
    public int testDbDivdeButInOneDb() throws Exception {
        // 改用户
        UserDo user = new UserDo();
        user.setId("2");
        user.setName("testDbDivdeButInOneDb");
        int reUser = userService.add(user);
        // 改日志1
        LogDo log1 = new LogDo();
        log1.setId("111");
        log1.setTime("2025-01-01 11:11:11");
        log1.setContent("testDbDivdeButInOneDb");
        log1.setDepartId("0");
        int reLog1 = logService.add(log1);
        // 改日志2
        LogDo log2 = new LogDo();
        log2.setId("222");
        log2.setTime("2025-02-02 11:11:11");
        log2.setContent("testDbDivdeButInOneDb");
        log2.setDepartId("0");
        int reLog2 = logService.add(log2);
        // 抛出异常
        if (true) {
            throw new Exception("err");
        }
        return reUser + reLog1 + reLog2;
    }

正常回滚,说明当表在一个库中时,使用@Transactional(rollbackFor = Exception.class)即可。

3.3 涉及分库表,且分库表处于多个库

我们再构造一个在不同库的例子,看能否回滚。

	/**
     * 涉及分库表,且分库表处于多个库
     */
    @Transactional(rollbackFor = Exception.class)
    public int testDbDivdeButInTwoDb() throws Exception {
        // 改日志1
        LogDo log1 = new LogDo();
        log1.setId("111");
        log1.setTime("2025-01-01 11:11:11");
        log1.setContent("testDbDivdeButInOneDb");
        log1.setDepartId("0");//在库ds0中!
        int reLog1 = logService.add(log1);
        // 改日志2
        LogDo log2 = new LogDo();
        log2.setId("222");
        log2.setTime("2025-02-02 11:11:11");
        log2.setContent("testDbDivdeButInOneDb");
        log2.setDepartId("1");//在库ds1中!
        int reLog2 = logService.add(log2);
        // 抛出异常
        if (true) {
            throw new Exception("err");
        }
        return reLog1 + reLog2;
    }

实测证明依然回滚。

3.4 涉及分库表,且运行中某库停机

我们启动项目后,将ds1停止运行,然后测试,依然可以。

4. 小结

经查询文档,在不指定TransactionType,默认采用的TransactionType.LOCAL枚举值,这个用法已经够用了。

可以通过@ShardingTransactionType(TransactionType.XA)改为其他事务类型。

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

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

相关文章

【Azure 架构师学习笔记】- Azure Function (2) --实操1

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Function 】系列。 接上文【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍 前言 上一文介绍了环境搭建,接下来就在本地环境下使用一下。 环境准备 这里我下载了最新的VS studio&…

【Vue3 入门到实战】3. ref 和 reactive区别和适用场景

目录 ​编辑 1. ref 部分 1.1 ref定义基本数据类型 1.2 ref 定义引用数据类型 2. reactive 函数 3. ref 和 reactive 对比 3.1 原理 3.2 区别 3.3 使用原则 在 Vue 3 中 ref 和 reactive 是用于创建响应式数据的两个核心函数。它们都属于 Composition API 的一部分&…

k8s集群换IP

k8s集群搭建及节点加入时需要确定IP,但安装完成后设备移动到新环境可能出现网段更换或者IP被占用的情况,导致无法ping通节点或者无法打开原IP的服务。 解决方法为保持原有IP不更换,给网卡再加一个IP 这边使用两个ubuntu虚拟机模拟服务器和w…

学习threejs,使用FlyControls相机控制器

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.FlyControls 相机控制…

奉加微PHY6230兼容性:部分手机不兼容

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

Unity3D仿星露谷物语开发23之拿起道具的动画

1、目标 当点击库存栏上可以carry的道具时,首先arms替换为carry状态,同时手上拿着被点击的道具。当再次点击同一个道具时,ams替换为idle状态,手上放下之前的道具。 这个最主要的是要学会使用AnimatorOverrideController类。 2、…

【Unity3D】远处的物体会闪烁问题(深度冲突) Reversed-Z

知识点:深度冲突、像素闪烁现象、Reversed-Z(反向Z)、浮点数精度问题 前提概要:深度值都是由32位浮点数存储 原因:深度冲突,多个物体之间无法正确地渲染远近关系,出现上一帧可能是A物体在B物体…

彻底理解JVM类加载机制

文章目录 一、类加载器和双亲委派机制1.1、类加载器1.2、双亲委派机制1.3、自定义类加载器1.4、打破双亲委派机制 二、类的加载 图片来源:图灵学院   由上图可知,创建对象,执行其中的方法,在java层面,最重要的有获取…

【2024年华为OD机试】 (A卷,200分)- 快递投放问题(Java JS PythonC/C++)

一、问题描述 题目解析 题目描述 有 N 个快递站点用字符串标识,某些站点之间有道路连接。每个站点有一些包裹要运输,每个站点间的包裹不重复。路上有检查站会导致部分货物无法通行,计算哪些货物无法正常投递。 输入描述 第一行输入 M N&…

python爬虫爬取淘宝商品比价||淘宝商品详情API接口

最近在学习北京理工大学的爬虫课程,其中一个实例是讲如何爬取淘宝商品信息,现整理如下: 功能描述:获取淘宝搜索页面的信息,提取其中的商品名称和价格 探讨:淘宝的搜索接口 翻页的处理 技术路线:requests…

【大数据】机器学习------支持向量机(SVM)

支持向量机的基本概念和数学公式: 1. 线性可分的支持向量机 对于线性可分的数据集 ,其中(x_i \in R^d) 是特征向量 是类别标签,目标是找到一个超平面 ,使得对于所有 的样本 ,对于所有(y_i -1) 的样本,…

服务器数据恢复—EMC存储POOL中数据卷被删除的数据恢复案例

服务器数据恢复环境&故障: EMC Unity 400存储连接了2台硬盘柜。2台硬盘柜上一共有21块硬盘(520字节)。21块盘组建了2组RAID6:一组有11块硬盘,一组有10块硬盘。 在存储运行过程中,管理员误操作删除了 2组…

Ubuntu系统备份与还原

Ubuntu系统备份与还原 前言ClonezillaTimeshift安装图形界面使用命令行使用 前言 Linux系统备份软件有Clonezilla和TimeShift。 使用Clonezilla需要准备USB启动盘,而Timeshift不需要。 因此推荐使用Timeshift进行备份与还原。 Clonezilla 官网:https:…

CSS:语法、样式表、选择器

目录 一、语法 二、创建 外部样式表 内部样式表 内联样式 三、选择器 ID选择器 类选择器 伪类选择器 :hover a:link a:active a:visited 属性选择器 伪元素选择器 ::first-letter ::first-line ::selection ::placeholder ::before 和::after 通配选择器 标…

记录一次 centos 启动失败

文章目录 现场1分析1现场2分析2搜索实际解决过程 现场1 一次断电,导致 之前能正常启动的centos 7.7 起不来了有部分log , 关键信息如下 [1.332724] XFS(sda3): Internal error xfs ... at line xxx of fs/xfs/xfs_trans.c [1.332724] XFS(sda3): Corruption of in-memory data…

YOLOv5训练长方形图像详解

文章目录 YOLOv5训练长方形图像详解一、引言二、数据集准备1、创建文件夹结构2、标注图像3、生成标注文件 三、配置文件1、创建数据集配置文件2、选择模型配置文件 四、训练模型1、修改训练参数2、开始训练 五、使用示例1、测试模型2、评估模型 六、总结 YOLOv5训练长方形图像详…

“AI智能防控识别系统:守护安全的“智慧卫士”

在如今这个科技飞速发展的时代,安全问题始终是大家关注的焦点。无论是企业园区、学校校园,还是居民社区,都希望能有一双“慧眼”时刻守护着,及时发现并防范各种安全隐患。而AI智能防控识别系统,就像一位不知疲倦、精准…

使用FFmpeg和Python将短视频转换为GIF的使用指南

使用FFmpeg和Python将短视频转换为GIF的使用指南 在数字时代,GIF动图已成为表达情感和分享幽默的重要媒介。无论是社交媒体上的搞笑片段还是创意项目中的视觉效果,GIF都能迅速抓住观众的注意力。然而,很多人不知道如何将短视频转换为GIF。本…

黑马Java面试教程_P1_导学与准备篇

系列博客目录 文章目录 系列博客目录导学Why?举例 准备篇企业是如何筛选简历的(筛选简历的规则)HR如何筛选简历部门负责人筛选简历 简历注意事项简历整体结构个人技能该如何描述项目该如何描述 应届生该如何找到合适的练手项目项目来源找到项目后,如何深入学习项目…

【前端动效】HTML + CSS 实现打字机效果

目录 1. 效果展示 2. 思路分析 2.1 难点 2.2 实现思路 3. 代码实现 3.1 html部分 3.2 css部分 3.3 完整代码 4. 总结 1. 效果展示 如图所示,这次带来的是一个有趣的“擦除”效果,也可以叫做打字机效果,其中一段文本从左到右逐渐从…