Spring+Mybatis开发环境中的SqlSessionTemplate对象为什么是线程安全的?为什么不会发生数据库连接泄露?

问题一:SqlSessionTemplate对象为什么是线程安全的?
    SqlSessionTemplate是SqlSession接口的一个实现,为Spring容器所独有,一般在Spring容器中定义如下:


	  

默认scope是singleton(单例),既然是单例,凭什么SqlSessionTemplate对象还是线程安全的?

答案一:
    SqlSessionTemplate对象中定义了对象SqlSessionProxy动态代理,利用动态代理来执行增删改查,动态代理中的动态处理器SqlSessionInterceptor中利用SqlSessionUtils.getSqlSession()方法得到SqlSession。进入getSqlSession()查看源码,发现其中的SqlSession作为成员变量保存在SqlSessionHolder对象中,而SqlSessionHolder对象又保存在当前事务管理类TransactionSynchronizationManager的线程安全变量resources中。事务管理类TransactionSynchronizationManager中的成员变量会在事务结束后被清空。因此,SqlSessionTemplate在同一个线程的同一个事务中是线程安全的。


问题二:调用SqlSessionTemplate对象后,并没有进行连接释放,为什么不会造成连接泄露?
    如果新建一个SqlSession而不释放,即不调用session.close(),则数据库连接数量会暴增,直到数据崩溃不能访问,这就叫做连接泄露。
答案二:
    根据问题一的分析,SqlSessionTemplate对象在一个具体线程内,会创建一个线程安全的SqlSession对象且是单例的,因此不释放也不会发生SqlSession无限增多的情况。


问题三:如果不依托于Spring框架,该如何使用SqlSession以确保线程安全和不发生连接泄露?
答案三:

SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
sqlSession = SqlSessionManager.newInstance(sqlSessionFactory);

其中org.apache.ibatis.session.SqlSessionManager类所创建的SqlSession是线程安全的,且会自动释放。


参考:https://www.cnblogs.com/daniels/p/8242592.html
https://blog.csdn.net/zgrgfr/article/details/53304953
http://www.cnblogs.com/daxin/p/3544188.html
https://www.cnblogs.com/zcmzex/p/9005194.html

你可能感兴趣的:(数据库,Java)