请直接看原文
原文链接:多线程与数据库事务以及数据库连接之间的关系 – 知乎 (zhihu.com)
——————————————————————————————————————————–
今天我们来梳理一下, 多线程、数据库事务、数据库连接之间的关系
单线程下
先来看一段代码
@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);
}
这段代码说明了什么?
问题来了,这三个与数据库的操作,与数据库建立的连接是同一个吗?还是不同的连接呢?
假如说,当我们有一个线程A来执行此方法时,发现此方法开启了事务,
而事务,又是基于数据库Connection连接的,这个事务中有三个操作数据库的dao方法,此时线程A会用同一个connection连接操作这三个dao方法.
我们再来看下事务,假如说程序有一个方法,一个方法里调了两个接口方法,每个接口方法都开启了事务,每个接口都有三个dao方法的操作.如下面类似的代码
结果就是如下图:一个线程对应一个connection数据库连接, 这个连接上可以有两个事务,且两个事务都能正常执行且互不影响.
多线程下
假如说有两个线程同时进入这个接口,线程操作数据库里数据时,那么他们的关系又会是什么样的呢?
从图中我们可以看到,两个线程分别获得不同的数据库连接,各自有各自的事务,这个时候,就是前文说的多事务
总结
1.同一时刻,不同的线程会获取到不同的数据库连接Connection对象,各自开启各自的事务, 每个事务之间是由mysql自己来实现事务的隔离性的.
2.开启事务后,为什么三个dao方法可以获得同一个Connection?
当前线程把connection对象存到了ThreadLocal中, ThreadLocal 中保存了一个 map,key 是DataSource数据源,value 是数据库连接Connection。当一个线程多次操作数据库的时候(很多个dao),每次都可以获得同一个数据库连接.
3.为什么要确保是同一个数据库连接?
是因为数据库的事务是基于数据库连接的,如果这个线程操作了三次dao每次连接都不一样,那么就没办法保证这三次操作被同一个事务所管理.
4.什么是本地事务?
就是几个dao方法只被一个线程操作,然后就只产生了一个connection连接对象. 这才能就是说是本地事务.
原文地址:https://blog.csdn.net/weixin_70280523/article/details/134618476
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_7965.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!