美文网首页
mybatis是如何配合spring事务的?

mybatis是如何配合spring事务的?

作者: M_lear | 来源:发表于2023-01-10 14:57 被阅读0次

必备知识:事务处理、sql执行最终都是依赖JDBC连接去操作。并且一个事务只能在一个连接中执行。

在mybatis和spring的搭配中,spring负责事务管理,mybatis负责sql执行。

其中的关键问题就是,在一个事务中,如何保证spring和mybatis使用的是同一个连接?

答案就是,连接也由spring管理,并对外提供:

DataSourceUtils.getConnection()          // 获取连接
DataSourceUtils.releaseConnection()      // 释放连接

mybatis就是通过这俩静态方法获取和释放连接。


mybatis定义了个SqlSession封装JDBC连接,一个SqlSession对象对应一个JDBC连接。

那么我们接下来看看,在事务和非事务中,SqlSession是如何创建和销毁的。

代码在mybatis-spring的SqlSessionTemplate类中。

这个类基于JDK的动态代理,为mapper的方法织入sqlsession的获取和销毁逻辑。

图1.png

1. 获取sqlsession(对应图1中的第1步)

图2.png

spring事务管理器TransactionSynchronizationManager(见图3),使用ThreadLocal保存事务资源。(这是spring事务失效的原因之一,不能在事务中使用多线程,因为这会导致一个事务从ThreadLocal获取到的JDBC连接不是一个连接,而一个事务只能一个连接中执行。)

spring为什么这么做?为什么不为每个事务分配一个唯一id去做缓存?我理解是因为一个事务中的sql必须在一个连接中顺序执行,你开多线程也没有意义。

图3.png

2. 销毁sqlsession(对应图1中的第3步)

图4.png

released方法并没有关闭sqlsession,仅仅是减了下引用计数:

图5.png

结论:
在事务期间,执行的所有mapper方法共用一个sqlsession。
在非事务期间,每执行一个mapper方法都会单独创建一个sqlsession。

相关文章

网友评论

      本文标题:mybatis是如何配合spring事务的?

      本文链接:https://www.haomeiwen.com/subject/ncapcdtx.html