spring的线程、数据库连接和事务之间的关系

问题的由来:

        通常我们在直接操作数据库的时候,先连上数据库,然后执行sql,那么执行一次sql就有一次事务提交,同一个连接下可以有无数的事务,而在开发的时候通常我们都是在service里面进行数据库操作比如:

    @Transactional
    @Override
    public void myTest(Test updateVO) {
        Test test = testDao.selectById(updateVO.getId());
        test.setName("test");
        testDao.updateById(test);
        testDao.deleteById(test.getId());
    }

        上面这个service方法里面进行了三次数据库操作,那么这三次操作是在一个service方法里面,方法开启了事务,那么问题是:这三次共享一次事务?还是说执行一次sql就是一个事务?spring里面的每一次线程与事务又有什么样的关系?他们是共享的一个数据库连接么?这些其实是可以从源码中看到的,但是今天不说源码,这里的事务关系,重点是不说源码

        解决问题

        1.在不开启事务控制的时候,事务与线程没有直接关系,为什么是没有直接关系:关系是因为要线程调用才能创建连接,才能有事务,直接是因为事务的控制是与每一条sql相关的,不是线程控制的。

        下图可以感受到:在不开启事务的时候dao每操作一次数据库都会穿件新的sqlsession其实就是创建一个连接。

        2.在开启事务的事务控制的时候,事务与线程有直接关系。

                从下图可以感受到:在开启了事务控制的时候,线程调用被控制方法,并且使用dao对数据库进行了操作,那么这个方法中只会创建一次sqlsession,以后的每次操作都只会用这一个连接。

         以上两点发生的原因分析:

                如果开启事务控制,一个方法想要用同一个事务控制,而事务是基于连接的,那么必然这个方法只能有一个连接,因此不管这个方法里面原本有多少个事务,多少次数据库操作,多少个dao,都只能共用一次连接。

        3.当同一个Thread调用多个service方法,并且这些方法都被引入的事务控制,当进入第一个方法时创建了sqlsession,进入第二方法时也创建sqlsession,那肯定是不同的事务控制了,这里我从源码中查看是因为:虽然ConnetionHoler是ThreadLocal的resources存储的,但是在上一次调用service完成的时候,事务提交后会将连接、session等给close,下一次再调用service接口的时候会拿datasource重新创建连接(但是有人说是同一个连接,这里谁能确定的可以告知一下,有可能我理解错误了)。

         从下图中可以感受到:同一线程在访问不同的service方法时即使都开启了事务控制,那么他们sqlsession也是不同的。

         4.多线程下数据库连接确定一定以及肯定是不同的,否则事务在提交会是混乱的,就像我们常见的多线程并发问题一样。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值