您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
多线程与数据库事务及数据库连接之间的关系
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
多线程与数据库事务及数据库连接之间的关系
自猿其说Tech
2021-08-16
IP归属:未知
24760浏览
Sql
计算机编程
### 1 疑问 今天我们来梳理一下, 多线程、数据库事务、数据库连接之间的关系 前文我们提到过,数据库事务的相关知识,具体可以看这篇文章京东面试官问我:“<a href="https://developer.jdcloud.com/article/1966" target="_blank">聊聊MySql事务,MVCC?”</a>,不过,我们说的多事务和平常中说的多线程有什么关系呢?是一个线程对应一个事务吗?多线程就是多事务?项目中都有数据库连接池,那其中的数据库连接和事务,线程又有什么关系呢?今天就来好好聊一下这个话题,缕清关系,更方便以后的CRUD ### 2 单线程下 **先来看一段代码** ```java @Transactional @Override public void updateTest(Test updateVO) { Test test = testMapper.selectByPrimaryKey(updateVO.getId()); System.out.println("当前线程是: "+Thread.currentThread().getName()+"查出来的值是"+JSON.toJSON(test).toString()); testMapper.updateByPrimaryKey(updateVO); testMapper.deleteByPrimaryKey(2); } ``` **这段代码说明了什么?** - 开启了事务 - 其中有三次和数据库交互的操作 问题来了,这三个与数据库的操作,与数据库建立的连接是同一个吗?还是不同的连接呢? - 开启事务的话,建立一次连接 :控制台输出Fetched SqlSession的字样 - 没开启事务的话,建立三次连接 :控制台输出Creating a new SqlSession的字样 为什么会这样呢,就是因为 我们经常说的事务 假如说,当我们有一个线程A来执行此方法时,发现此方法开启了事务,而事务,又是基于数据库Connection连接的,这个事务中有三个操作数据库的dao方法,如果想用一个事务来管三个操作dao的方法,那么这三个dao的方法必须基于同一个Connection连接,此线程A会获得数据库连接池中的数据库连接ConnectionA ![](//img1.jcloudcs.com/developer.jdcloud.com/e6d0a921-95aa-44a4-a826-17ff1a7d46ac20210816114603.png) 我们再来看下事务,假如说程序有两个接口,每个接口都开启了事务,每个接口都有三个dao方法的操作。 ![](//img1.jcloudcs.com/developer.jdcloud.com/b6307a0c-94fd-4419-92a8-dab6c176a99220210816114617.png) 结论:单个线程Thread持有一个数据库连接Connection ,这个连接上可以有多个事务 ### 3 多线程下 假如说有两个线程同时进入这个接口,线程操作数据库里数据时,那么他们的关系又会是什么样的呢? ![](//img1.jcloudcs.com/developer.jdcloud.com/ca628b22-3a3a-4d10-8300-d6eec70f4b3820210816114700.png) 从图中我们可以看到,两个线程分别获得不同的数据库连接,各自有各自的事务,这个时候,就是前文说的多事务 这时候有一个疑问就是,当一个方法有事务,且这个方法内开启了子线程异步执行,那么父子线程之间的事务会有什么关系吗? **没有关系:**子线程出现异常,父线程不会回滚 因为spring是通过ThreadLocal来管理数据库连接的,而threadLocal无法将父线程的连接传递给子线程,而事务又是基于连接的。 ### 4 事务特性 我们从图中可以看到,两个线程各自的事务,开始和提交的时间有时候不一致,有先提交和后提交的,那他们会互相影响吗?这个时候,我们常说的事务特性ACID里面的I(隔离性),就体现出来他的重要性了 如果我们设置成了可重复读,那么A事务对数据库的操作对于B事务来说,就是透明的,B事务感知不到 如果要是设置成了读已提交,那么A事务对数据库的操作对于B事务来说,就不是透明的,事务B会读取事务A改后的数据在进行操作 具体详情可以看这篇文章 : 京东面试官问我:“<a href="https://developer.jdcloud.com/article/1966" target="_blank">聊聊MySql事务,MVCC?</a>” 强烈建议这两篇文章一起食用,效果更佳,这样就可以整体串起来了 ### 5 总结 同一时刻,不同的线程会获取到不同的数据库连接,各自开启各自的事务,事务之间的具体联系就靠事务的特性ACID之隔离性的设置来确定 如果不同的线程获取的是同一个数据库连接,就会产生事务冲突,A线程创建了A事务,B线程创建了B事务,有可能A事务还未提交,B事务就提交了,那么这个时候多线程执行的dao方法相关的数据库操作都会生效,而A事务其他方法还未执行,导致问题发生,而事务的隔离性是基于不同的连接的,避免不了这种情况。 开启事务后,为什么三个dao方法可以获得同一个Connection? spring是通过 ThreadLocal 来保证同一个线程在其生命周期中,当多次操作数据库的时候(很多个dao),每次都可以获得同一个数据库连接,为什么要确保是同一个数据库连接?是因为数据库的事务是基于数据库连接的,如果这个线程操作了三次dao每次连接都不一样,那么就没办法保证这三次操作被同一个事务所管理 你要问我我怎么知道的,微信搜索:java小杰要加油,有更多精彩 ------------ 自猿其说Tech-JDL京东物流技术发展部 作者:中台技术部 邢焕杰 ![](//img1.jcloudcs.com/developer.jdcloud.com/f04c37ce-7ca6-403f-a875-3b8737b3fd6820210816114904.png)
原创文章,需联系作者,授权转载
上一篇:京东APP后台多端融合架构代码重构实战
下一篇:AspectJ浅析系列(二)-切入点和通知
相关文章
【技术干货】企业级扫描平台EOS关于JS扫描落地与实践!
开发也要防沉迷--IDEA插件教程
如何保证MySQL和Redis的数据一致性?10分钟带你搞定!
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号