Mybatis和Spring整合后sqlsession啥時候關閉的


https://www.cnblogs.com/juniorMa/p/13933192.html 

  在上一篇中,講到一個非常重要的知識點,那就是每一個mapper對象的代理類執行方法的時候,都是每次都會new 一個SqlSession出來

  但是我當時還有兩個疑問

  1 在SqlSessionInterceptor中我沒有發現執行close的地方

  2 為什么每次獲取sqlsession的時候,判斷ThreadLocal里面的緩存都是null呢?

  經過不懈的努力,終於找到了原因,那就是由於使用了Spring提供的事務,這些資源的釋放都是事務做的

  代碼在

SqlSessionUtils的內部類 SqlSessionSynchronization 的方法
@Override
    public void beforeCompletion() {
      // Issue #18 Close SqlSession and deregister it now
      // because afterCompletion may be called from a different thread
      if (!this.holder.isOpen()) {
        if (logger.isDebugEnabled()) {
          logger.debug("Transaction synchronization deregistering SqlSession [" + this.holder.getSqlSession() + "]");
        }
        TransactionSynchronizationManager.unbindResource(sessionFactory);
        this.holderActive = false;
        if (logger.isDebugEnabled()) {
          logger.debug("Transaction synchronization closing SqlSession [" + this.holder.getSqlSession() + "]");
        }
        this.holder.getSqlSession().close();
      }
    }

  AbstractPlatformTransactionManager 

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
        try {
            boolean beforeCompletionInvoked = false;
            try {
                prepareForCommit(status);
                triggerBeforeCommit(status);
                triggerBeforeCompletion(status);
                beforeCompletionInvoked = true;
                boolean globalRollbackOnly = false;
protected final void triggerBeforeCompletion(DefaultTransactionStatus status) {
        if (status.isNewSynchronization()) {
            if (status.isDebug()) {
                logger.trace("Triggering beforeCompletion synchronization");
            }
            TransactionSynchronizationUtils.triggerBeforeCompletion();
        }
    }
public static void triggerBeforeCompletion() {
        for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
            try {
                synchronization.beforeCompletion();
            }
            catch (Throwable tsex) {
                logger.error("TransactionSynchronization.beforeCompletion threw exception", tsex);
            }
        }
    }

  其實怎么做原因也很明顯,只有每次都new,每次都釋放,才能保證多線程不報錯

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM