SqlSessionHolder在Mybatis中是用来做什么的?

What the SqlSessionHolder is used to do in Mybatis?

在SqlSessionTemplate中,getSqlSession和closeSqlSession方法都是操作SqlSessionHolder,但我认为不是必须这样做,Spring管理事务并提供ConnectionHolder,事务是关于连接的。

SqlSessionHolder holder = (SqlSessionHolder) getResource(sessionFactory);

if (holder != null && holder.isSynchronizedWithTransaction()) {
   if (holder.getExecutorType() != executorType) {
       throw new TransientDataAccessResourceException("Cannot change the ExecutorType when there is an existing transaction");
   }

   holder.requested();

   if (logger.isDebugEnabled()) {
      logger.debug("Fetched SqlSession [" + holder.getSqlSession() + "] from current transaction");
   }

   return holder.getSqlSession();
}

if (logger.isDebugEnabled()) {
  logger.debug("Creating a new SqlSession");
}

SqlSession session = sessionFactory.openSession(executorType);

为什么我们需要SqlSessionHolder?

Mybatis出于性能原因,有些session实现并不是无状态的,它们包含本地缓存。

因此,虽然理论上可以将会话实现为连接周围的薄包装,并在每次需要时创建新的会话实例(什么会从 spring 获取绑定到当前事务的连接)在观察到缓存命中的情况下会有性能损失。