spring事务管理源码解析之事务提交和回滚

本文转自“天河聊技术”微信公众号spring

 

说在前面数据库

@Transactional实现,接着上篇文章继续微信

正文ide

事务回滚源码解析this

上次解析到这个方法org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction的这一行debug

 

执行事务方法code

retVal = invocation.proceedWithInvocation();
catch (Throwable ex) {
   // target invocation exception 执行业务方法异常
   completeTransactionAfterThrowing(txInfo, ex);
   throw ex;
}

进入到这个方法orm

org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing事务

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
      if (txInfo != null && txInfo.getTransactionStatus() != null) {
         if (logger.isTraceEnabled()) {
            logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
                  "] after exception: " + ex);
         }
//       有指定的异常回滚,异常类型是检查异常或者是非检查异常,非检查性异常自动回滚
         if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
//             事务回滚
               txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            }
            catch (TransactionSystemException ex2) {
               logger.error("Application exception overridden by rollback exception", ex);
               ex2.initApplicationException(ex);
               throw ex2;
            }
            catch (RuntimeException | Error ex2) {
               logger.error("Application exception overridden by rollback exception", ex);
               throw ex2;
            }
         }
         else {
            // We don't roll back on this exception.
            // Will still roll back if TransactionStatus.isRollbackOnly() is true.
            try {
               txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
            }
            catch (TransactionSystemException ex2) {
               logger.error("Application exception overridden by commit exception", ex);
               ex2.initApplicationException(ex);
               throw ex2;
            }
            catch (RuntimeException | Error ex2) {
               logger.error("Application exception overridden by commit exception", ex);
               throw ex2;
            }
         }
      }
   }
事务回滚
               txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());

进入到这个方法ip

org.springframework.transaction.support.AbstractPlatformTransactionManager#rollback

@Override
   public final void rollback(TransactionStatus status) throws TransactionException {
//    事务是否已经完成
      if (status.isCompleted()) {
         throw new IllegalTransactionStateException(
               "Transaction is already completed - do not call commit or rollback more than once per transaction");
      }

      DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
//    执行事务回滚
      processRollback(defStatus, false);
   }
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
      try {
         boolean unexpectedRollback = unexpected;

         try {
//          事务资源解绑
            triggerBeforeCompletion(status);

//          事务是否有回滚点
            if (status.hasSavepoint()) {
               if (status.isDebug()) {
                  logger.debug("Rolling back transaction to savepoint");
               }
//             事务状态回退到回滚点
               status.rollbackToHeldSavepoint();
            }
            else if (status.isNewTransaction()) {
               if (status.isDebug()) {
                  logger.debug("Initiating transaction rollback");
               }
               doRollback(status);
            }
            else {
               // Participating in larger transaction参与更大的交易
               if (status.hasTransaction()) {
                  if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                     if (status.isDebug()) {
                        logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
                     }
                     doSetRollbackOnly(status);
                  }
                  else {
                     if (status.isDebug()) {
                        logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
                     }
                  }
               }
               else {
                  logger.debug("Should roll back transaction but cannot - no transaction available");
               }
               // Unexpected rollback only matters here if we're asked to fail early若是咱们被要求提早失败,那么意外的回滚就很重要了。
               if (!isFailEarlyOnGlobalRollbackOnly()) {
                  unexpectedRollback = false;
               }
            }
         }
         catch (RuntimeException | Error ex) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw ex;
         }

         triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

         // Raise UnexpectedRollbackException if we had a global rollback-only marker若是咱们有一个仅用于全局回滚的标记,那么就会引起unexpected tedrollbackexception
         if (unexpectedRollback) {
            throw new UnexpectedRollbackException(
                  "Transaction rolled back because it has been marked as rollback-only");
         }
      }
      finally {
         cleanupAfterCompletion(status);
      }
   }
         事务状态回退到回滚点
               status.rollbackToHeldSavepoint();
public void rollbackToHeldSavepoint() throws TransactionException {
      Object savepoint = getSavepoint();
      if (savepoint == null) {
         throw new TransactionUsageException(
               "Cannot roll back to savepoint - no savepoint associated with current transaction");
      }
//    事务回滚到事务回滚点
      getSavepointManager().rollbackToSavepoint(savepoint);
//    释放事务回滚点
      getSavepointManager().releaseSavepoint(savepoint);
      setSavepoint(null);
   }

返回到这个方法

org.springframework.transaction.support.AbstractPlatformTransactionManager#processRollback这行

   事务回滚
               doRollback(status);
@Override
   protected void doRollback(DefaultTransactionStatus status) {
//    获取事务
      DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
//    获取数据库链接
      Connection con = txObject.getConnectionHolder().getConnection();
      if (status.isDebug()) {
         logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
      }
      try {
//       事务回滚
         con.rollback();
      }
      catch (SQLException ex) {
         throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
      }
   }

事务提交源码解析

返回到这个方法org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing这行

 

事务提交

txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());

进入到这个方法org.springframework.transaction.support.AbstractPlatformTransactionManager#commit

@Override
   public final void commit(TransactionStatus status) throws TransactionException {
      if (status.isCompleted()) {
         throw new IllegalTransactionStateException(
               "Transaction is already completed - do not call commit or rollback more than once per transaction");
      }

      DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
//    若是是本地事务回滚
      if (defStatus.isLocalRollbackOnly()) {
         if (defStatus.isDebug()) {
            logger.debug("Transactional code has requested rollback");
         }
//       事务回滚
         processRollback(defStatus, false);
         return;
      }

//    全局事务回滚
      if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
         if (defStatus.isDebug()) {
            logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
         }
//       事务回滚
         processRollback(defStatus, true);
         return;
      }

//    事务提交
      processCommit(defStatus);
   }
//     事务提交
      processCommit(defStatus);
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
      try {
         boolean beforeCompletionInvoked = false;

         try {
            boolean unexpectedRollback = false;
//          准备提交
            prepareForCommit(status);
//          出发提交以前回调
            triggerBeforeCommit(status);
            triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;

            if (status.hasSavepoint()) {
               if (status.isDebug()) {
                  logger.debug("Releasing transaction savepoint");
               }
               unexpectedRollback = status.isGlobalRollbackOnly();
               status.releaseHeldSavepoint();
            }
            else if (status.isNewTransaction()) {
               if (status.isDebug()) {
                  logger.debug("Initiating transaction commit");
               }
               unexpectedRollback = status.isGlobalRollbackOnly();
//             事务提交
               doCommit(status);
            }
            else if (isFailEarlyOnGlobalRollbackOnly()) {
               unexpectedRollback = status.isGlobalRollbackOnly();
            }

            // Throw UnexpectedRollbackException if we have a global rollback-only若是咱们只进行全局回滚,那么将抛出unexpected tedrollbackexception
            // marker but still didn't get a corresponding exception from commit.可是仍然没有从commit获得相应的异常。
            if (unexpectedRollback) {
               throw new UnexpectedRollbackException(
                     "Transaction silently rolled back because it has been marked as rollback-only");
            }
         }
         catch (UnexpectedRollbackException ex) {
            // can only be caused by doCommit只能由doCommit引发吗
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
            throw ex;
         }
         catch (TransactionException ex) {
            // can only be caused by doCommit只能由doCommit引发吗
            if (isRollbackOnCommitFailure()) {
               doRollbackOnCommitException(status, ex);
            }
            else {
               triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            }
            throw ex;
         }
         catch (RuntimeException | Error ex) {
            if (!beforeCompletionInvoked) {
               triggerBeforeCompletion(status);
            }
            doRollbackOnCommitException(status, ex);
            throw ex;
         }

         // Trigger afterCommit callbacks, with an exception thrown there触发afterCommit回调,并在其中抛出一个异常
         // propagated to callers but the transaction still considered as committed.传播到调用者,但事务仍然被认为是提交的。
         try {
            triggerAfterCommit(status);
         }
         finally {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
         }

      }
      finally {
         cleanupAfterCompletion(status);
      }
   }

说到最后

本次解析仅表明我的看法,仅供参考。

相关文章
相关标签/搜索