spring本地事务与单/多线程

请直接看原文

原文链接:多线程与数据库事务以及数据库连接之间的关系 - 知乎 (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);
    }

这段代码说明了什么?

  • 开启了事务
  • 其中有三次和数据库交互的操作

问题来了,这三个与数据库的操作,与数据库建立的连接是同一个吗?还是不同的连接呢?

  • 开启事务的话,建立一次连接 :控制台输出Fetched SqlSession的字样
  • 没开启事务的话,建立三次连接 :控制台输出Creating a new SqlSession的字样

为什么会这样呢,就是因为 我们经常说的事务

假如说,当我们有一个线程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每次连接都不一样,那么就没办法保证这三次操作被同一个事务所管理.


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值