SqlSession的默认实现DefaultSqlSession是非线程安全的。所以我们真正开发的时候不会直接去使用它,而是使用其他实现。这些实现的核心都是通过操作代理对象,来实现线程安全的。
1.SqlSession接口实现展示
1.DefaultSqlSession真正干活的亲儿子。
2.代理对象包装了DefaultSqlSession,只为解决线程安全问题。
2.DefaultSqlSession为什么非线程安全
//defaultSqlSession底层获得connection的方式
protected Connection getConnection(Log statementLog) throws SQLException {
//当前的SqlSession已有connection就不在创建新的,所以线程不安全
Connection connection = transaction.getConnection();
if (statementLog.isDebugEnabled() || connectionLog.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection, statementLog);
} else {
return connection;
}
}
3.SqlSessionManger如何保证线程安全
SqlSessionManager通过动态代理实现线程安全。
1.未开启事务,代理内部每次创建一个新的DefaultSqlSession,并且没有对外暴露。
2.开启事务,DefaultSqlSession存放到localSqlSession。用户自己决定是否公用sqlSession。
详细的我们看看源码
public class SqlSessionManager implements SqlSessionFactory, SqlSession {
//实际放的是DefaultSessionFactory,因为他是SqlSessionFactoryBuilder生成。
private final SqlSessionFactory sqlSessionFactory;
//是一个SqlSession的代理对象,底层是