mybatis SqlSessionTemplate为什么线程安

2019-05-06  本文已影响0人  小七_8d72

mybatis SqlSessionTemplate使用的是动态代理,入口如下:

我们可以看到每次都是使用getSqlSession()来获取真是sqlsession的,而获取的sqlSession又是DefaultSqlSession,这个类我们知道他是线程不安全的,之前使用都是采用多实例模式,就是每次使用都new一个,但是spring采用了更加聪明的方式可以使它不需要每次new一个也可以保持线程安全(其实还是每次new一个sqlsession ,如果不在事务里)。

如下代码解释:从Spring事务管理器中得到一个SqlSession,如果需要创建一个新的。

首先努力从当前事务之外得到一个SqlSession,如果没有就创造一个新的。然后,如果Spring TX被激活,也就是事务被打开,且事务管理器是SpringManagedTransactionFactory时,将得到的SqlSession同当前事务同步

SqlSessionHolder holder = (SqlSessionHolder) getResource(sessionFactory);会在TransactionSynchronizationManager中在当前线程的事务管理中获取一个session的持有者。

registerSynchronization(new SqlSessionSynchronization(holder, sessionFactory));

此方法,//将holder, sessionFactory的同步加入本地线程缓存中ThreadLocal<Set<TransactionSynchronization>> synchronizations ,来判断同步是否激活,只要SpringTX被激活,就是true 

bindResource(sessionFactory, holder);

 //以sessionFactory为key,hodler为value,加入到TransactionSynchronizationManager管理的本地缓存ThreadLocal<Map<Object, Object>> resources中,确保事务里的每个线程使用自己的本地缓存

SqlSessionTemplate线程安全

上一篇下一篇

猜你喜欢

热点阅读