关于手动调用SqlSessionTemplate的connection,关闭问题

关于手动调用SqlSessionTemplate的connection,关闭问题

sqlSessionTemplate的原理

阅读源码发现sqlSessionTemplate里声明了一个代理,所有的增删改查方法都通过代理来实现

       this.sqlSessionProxy = (SqlSession) newProxyInstance(
        SqlSessionFactory.class.getClassLoader(),
        new Class[] { SqlSession.class },
        new SqlSessionInterceptor());

这里通过代理模式来设计的,重点类:SqlSessionInterceptor

  private class SqlSessionInterceptor implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      SqlSession sqlSession = getSqlSession(
          SqlSessionTemplate.this.sqlSessionFactory,
          SqlSessionTemplate.this.executorType,
          SqlSessionTemplate.this.exceptionTranslator);
      try {
        Object result = method.invoke(sqlSession, args);
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
          // force commit even on non-dirty sessions because some databases require
          // a commit/rollback before calling close()
          sqlSession.commit(true);
        }
        return result;
      } catch (Throwable t) {
        Throwable unwrapped = unwrapThrowable(t);
        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
          // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
          sqlSession = null;
          Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
          if (translated != null) {
            unwrapped = translated;
          }
        }
        throw unwrapped;
      } finally {
        if (sqlSession != null) {
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
        }
      }
    }
  }

当我们通过sqlSessionTemplate.getConnection()调用的时候,实际上通过代理类来实现,我们注意到代理类的finally方法里有一个释放连接的操作,因此当调用getConnection()结束以后,自动释放掉了连接,所以正确取得连接的方法应该是:

  this.st =sqlSessionTemplate;
 Connection connection = SqlSessionUtils.getSqlSession(
            this.st.getSqlSessionFactory(), this.st.getExecutorType(),
            this.st.getPersistenceExceptionTranslator()).getConnection()

你可能感兴趣的:(关于手动调用SqlSessionTemplate的connection,关闭问题)