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中,确保事务里的每个线程使用自己的本地缓存