Springboot中多线程数据库操作下的事务一致性问题的解决方案

news2024/11/26 0:29:44

文章目录

  • 1 代码实现
    • 1.1 正常情况
    • 1.2 异常情况
    • 总结

1 代码实现

1.1 正常情况

我们采用手动开启事务的方式

    public void add(CountDownLatch countDownLatch) {
        executor.submit(() -> {
                TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
                try {
                    ThreadTest obj = new ThreadTest();
                    obj.setColumnName("threadTest");
                    log.info("开始插入");
                    threadTestMapper.insert(obj);
                    countDownLatch.countDown();
                    // throw new RuntimeException("故意抛出错误测试是否会进行回滚");
                } catch (Exception e) {
                    log.info("出现异常了开始回滚");
                    dataSourceTransactionManager.rollback(transaction);
                } finally {
                    dataSourceTransactionManager.commit(transaction);
                }
            });
    }

insert方法中插入100条测试数据到数据库,通过手动开启事务的方式在每个子线程中开启各自的事务。注意注释的位置,首先测试没有错误的情况。

完整代码

@Service
@RequiredArgsConstructor
@Slf4j
public class ThreadTestServiceImplTwo extends ServiceImpl<ThreadTestMapper, ThreadTest>
    implements ThreadTestService{

    private final DataSourceTransactionManager dataSourceTransactionManager;
    private final TransactionDefinition transactionDefinition;
    private final ThreadTestMapper threadTestMapper;

    private
    static final ThreadPoolTaskExecutor executor;
    static {
        executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(15);
        executor.setQueueCapacity(100);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setKeepAliveSeconds(60);
        executor.initialize();
    }

    public void add(CountDownLatch countDownLatch) {
        executor.submit(() -> {
                TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
                try {
                    ThreadTest obj = new ThreadTest();
                    obj.setColumnName("threadTest");
                    log.info("开始插入");
                    threadTestMapper.insert(obj);
                    countDownLatch.countDown();
                    // throw new RuntimeException("故意抛出错误测试是否会进行回滚");
                } catch (Exception e) {
                    log.info("出现异常了开始回滚");
                    dataSourceTransactionManager.rollback(transaction);
                } finally {
                    dataSourceTransactionManager.commit(transaction);
                }
            });
    }

    public void insert() {
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for (int i = 0; i < 100; i++) {
            add(countDownLatch);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

测试类中测试insert方法

    @Test
    void testInsert() {
        threadTestService.insert();
    }

结果
正常插入100条数据
在这里插入图片描述

1.2 异常情况

把1.1中的方法 // throw new RuntimeException("故意抛出错误测试是否会进行回滚");取消注释即可,测试手动错误数据插入情况

   public void insert() {
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for (int i = 0; i < 100; i++) {
            add(countDownLatch);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    public void add(CountDownLatch countDownLatch) {
        executor.submit(() -> {
                TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
                try {
                    ThreadTest obj = new ThreadTest();
                    obj.setColumnName("threadTest");
                    log.info("开始插入");
                    threadTestMapper.insert(obj);
                    countDownLatch.countDown();
                    // 手动错误
                    throw new RuntimeException("故意抛出错误测试是否会进行回滚");
                } catch (Exception e) {
                    log.info("出现异常了开始回滚");
                    dataSourceTransactionManager.rollback(transaction);
                } finally {
                    dataSourceTransactionManager.commit(transaction);
                }
            });
    }

结果
可以看到线程发生错误(截图为部分线程)开始回滚数据
在这里插入图片描述
数据库理所当然没有数据,完成了事务的控制
在这里插入图片描述

总结

难道我们真的控制了多线程的事务吗?
上面测试的仅仅是所有的线程各自发生了错误,并且各自线程完成了自己线程事务的回滚,假设某一个线程没有错误,某个线程有错误,如何回滚所有线程事务呢?是不是和分布式事务有点类似了呢?所以通过上述方法是没有办法处理部分错误部分正确的情况!

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

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

相关文章

【HTML】HTML学习之引入CSS样式表

1、CSS样式规则 选择器{属性1:属性值1; 属性2:属性值2; 属性3:属性值3;}2、HTML引入CSS样式表 2.1、行内式 行内式也称为内联样式&#xff0c;是通过标签的style属性来设置元素的样式&#xff0c;其基本语法格式如下: <标签名 style"属性1:属性值1; 属性2:属性值2;…

Proxy/Skeleton

设计模式之&#xff08;十二&#xff09;代理模式_skeleton proxy 模式-CSDN博客 在RMI中&#xff0c;客户端可以通过一个桩&#xff08;Stub&#xff09;对象与远程主机上的业务对象进行通信&#xff0c;由于桩对象和远程业务对象接口的一致&#xff0c;因此对于客户端而言&am…

Maven的一些相关知识【重修】《包括私服搭建!》

mvnrepository.com Maven 下载jar包的位置&#xff01; 【该部分有教程】 这是什么nb代码投稿视频-这是什么nb代码视频分享-哔哩哔哩视频

python之matplotlib (6 等高线和热力图)

等高线 import numpy as np import matplotlib.pyplot as pltdef f(x,y):return (1-x/2x**5y**3)*np.exp(-x**2-y**2) n256 xnp.linspace(-3,3,n) yx X,Ynp.meshgrid(x,y) plt.contourf(X,Y,f(X,Y),8,alpha0.75,cmapviridis) plt.colorbar() Cplt.contour(X,Y,f(X,Y),8,colors…

第64期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

免费图形化nginx管理工具nginxWebUI

nginxWebUI是一款图形化管理nginx配置得工具, 可以使用网页来快速配置nginx的各项功能, 包括http协议转发, tcp协议转发, 反向代理, 负载均衡, 静态html服务器, ssl证书自动申请、续签、配置等, 配置好后可一建生成nginx.conf文件, 同时可控制nginx使用此文件进行启动与重载, 完…

Linux基础软件-软件安装

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux进阶部分又分了很多小的部分,我们刚讲完了Linux日常运维。讲的那些东西都算是系统自带的&#xff0c;但是Linux作为一个…

mklink 命令详解

mklink 命令详解 在命令提示符中输入 mklink 可以查看相关的运行命令。 创建符号链接。MKLINK [[/D] | [/H] | [/J]] Link Target/D 创建目录符号链接。默认为文件符号链接。/H 创建硬链接而非符号链接。/J 创建目录联接。Link 指定新的符号链接名称。Targ…

前端3d动画-----平移 transform: translate3d()

必须加这个属性&#xff1a;transform-style: preserve-3d; perspective: 900px; 设置了景深才能感到近大远小的感觉 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible&q…

CTF中的换表类Crypto题目

目录 [安洵杯 2019]JustBase[SWPUCTF 2021 新生赛]traditional字符替换解密 [BJDCTF 2020]base??字符替换 --》 base64解密 [安洵杯 2019]JustBase VGhlIGdlbxvZ#kgbYgdGhlIEVhcnRoJ#Mgc#VyZmFjZSBpcyBkb!pbmF)ZWQgYnkgdGhlIHBhcnRpY#VsYXIgcHJvcGVydGllcyBvZiB#YXRlci$gUHJ…

图神经网络教程3——循环图神经网络-2

目录 计算下游输出 序列图数据的扩展 图长短期记忆网络 循环转换在RGNN应用于图分类时的作用 数据集 算法 结果和讨论 门控循环单元 优缺点 前文索引 本篇是GRNN的第二篇文章&#xff0c;点击此处可到达第一篇文章的位置。 计算下游输出 一旦我们以图中的每个顶点为…

webm格式怎么转换成mp4?7个有效方法将webm转mp4

在数字媒体的浩瀚宇宙中&#xff0c;视频格式的多样性犹如繁星点点&#xff0c;既点亮了创意的火花&#xff0c;也铺设了内容分享的广阔道路。每一种视频格式都承载着其独特的技术优势与设计初衷&#xff0c;WebM便是其中一颗璀璨的新星&#xff0c;专为优化网络传输而生。它凭…

Unity | Shader基础知识(第二十二集:两次渲染)

目录 一、前言 二、“渲染两次” 三、本次成品介绍 四、第一次渲染代码 五、第二次渲染代码 六、截止目前的所有代码 七、调整代码 八、总结 一、前言 之前一直讲的shader文件中&#xff0c;都只写了一次CG代码。 为了大家对这部分的整体理解&#xff0c;我们这次渲…

微服务的保护

一、雪崩问题及解决方案 1.雪崩问题 微服务之间&#xff0c;一个微服务依赖多个其他的微服务。当一个微服务A依赖的一个微服务B出错时&#xff0c;微服务A会被阻塞&#xff0c;但其他不依赖于B的微服务不会受影响。 当有多个微服务依赖于B时&#xff0c;服务器支持的线程和并…

使用策略模式代替多个ifelse

传统的多个 public class OrderServiceImpl implements IOrderService {Overridepublic String handle(OrderDTO dto) {String type dto.getType();if ("1".equals(type)) {return "处理普通订单";} else if ("2".equals(type)) {return "…

PMP–知识卡片--产品管理知识体系

产品管理是公司为管理一个产品或者产品线的产品计划、产品市场和产品生命周期所采用的组织架构。产品管理是一个典型的强矩阵的管理方式。产品管理是企业或组织在产品生命周期中对产品规划、开发、生产、营销、销售和支持等环节进行管理的业务活动。 项目经理和产品有着直接、间…

xmind 2024下载,安装目录更改为其他盘

下载 最新版官网地址 更改目录

网络编程Day9_IO多路复用 20240821

运行1个服务器和2个客户端实现效果&#xff1a; 服务器和2个客户端互相聊天&#xff0c;服务器和客户端都需要使用select模型去实现 服务器要监视2个客户端是否连接&#xff0c;2个客户端是否发来消息以及服务器自己的标准输入流 客户端要监视服务器是否发来消息以及客户端自…

Go小技巧易错点100例(十七)

Go定时任务 在Go语言中&#xff0c;定时任务&#xff08;也称为定时器或cron作业&#xff09;具有多种作用&#xff0c;这些作用在应用程序的开发和运维中非常有用。以下是一些常见使用场景&#xff1a; 任务调度&#xff1a;定时任务可以在特定的时间点执行特定的任务&#…

云渲染服务大揭秘:为何它值得成为你的渲染新选择

云渲染是一种基于云计算的服务&#xff0c;它利用大量高性能计算机组成的集群来渲染高质量的图像和动画。这种服务能够显著加快3D动画或视觉效果项目的渲染速度&#xff0c;将原本可能需要数天的渲染任务缩短至数小时。 云渲染的优势 本文将探讨使用云渲染的好处&#xff0c;并…