spring事务管理-Spring 源码系列(6)总结

虾米姐 阅读:431 2021-05-02 14:53:44 评论:0

Spring事务抽象的是事务管理和事务策略。而实现则由各种资源方实现的。我们最常用的数据库实现:DataSourceTransactionManager

尝试阅读一下spring 的实现代码,由3个核心类:

1,PlatformTransactionManager

public interface PlatformTransactionManager { 
 
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; 
    void commit(TransactionStatus status) throws TransactionException; 
 
    void rollback(TransactionStatus status) throws TransactionException;

事务管理的抽象,一个获取事务状态,一个提交事务,一个回滚事务。

2,TransactionStatus

public interface TransactionStatus extends SavepointManager, Flushable { 
 
   boolean isNewTransaction(); 
 
   boolean hasSavepoint(); 
 
   void setRollbackOnly(); 
 
   boolean isRollbackOnly(); 
    
   void flush(); 
 
   boolean isCompleted(); 
 
}

事务状态的抽象

3,DefaultTransactionDefinition

public interface TransactionDefinition { 
 
    int getPropagationBehavior(); 
 
    int getIsolationLevel(); 
 
    int getTimeout(); 
 
    boolean isReadOnly(); 
 
    String getName(); 
 
}

事务策略抽象,1,事务传播行为,2,事务隔离级别,3,超时时间,4,只读属性

编程的方法实现事务管理使用简单代码:

transactionTemplate.execute(new TransactionCallback<String>() { 
   @Override 
   public String doInTransaction(TransactionStatus status) { 
      updatePayPrice(orderData, offer); 
      return null; 
   } 
});

类似下面的配置:

<bean id="txManager" 
   class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
   <property name="dataSource" ref="dataSource" /> 
</bean> 
 
<bean id="transactionTemplate" 
   class="org.springframework.transaction.support.TransactionTemplate" 
   p:transactionManager-ref="txManager" scope="prototype" />

TransactionTemplate继承了DefaultTransactionDefinition也就是TransactionDefinition默认实现,afterPropertiesSet方法检查transactionManager,

核心方法execute,其中四步:0.获取一个事务状态,1,执行业务逻辑  2,出现异常,3,没有异常事务提交
public class TransactionTemplate extends DefaultTransactionDefinition 
      implements TransactionOperations, InitializingBean { 
 
   /** Logger available to subclasses */ 
   protected final Log logger = LogFactory.getLog(getClass()); 
 
   private PlatformTransactionManager transactionManager; 
   public TransactionTemplate() { 
   } 
   public TransactionTemplate(PlatformTransactionManager transactionManager) { 
      this.transactionManager = transactionManager; 
   } 
   public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) { 
      super(transactionDefinition); 
      this.transactionManager = transactionManager; 
   } 
 
   public void setTransactionManager(PlatformTransactionManager transactionManager) { 
      this.transactionManager = transactionManager; 
   } 
 
   /** 
    * Return the transaction management strategy to be used. 
    */ 
   public PlatformTransactionManager getTransactionManager() { 
      return this.transactionManager; 
   } 
 
   @Override 
   public void afterPropertiesSet() { 
      if (this.transactionManager == null) { 
         throw new IllegalArgumentException("Property 'transactionManager' is required"); 
      } 
   } 
 
   @Override 
   public <T> T execute(TransactionCallback<T> action) throws TransactionException { 
   if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) { 
      return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action); 
   } 
   else { 
      // 0.获取一个事务状态 
      TransactionStatus status = this.transactionManager.getTransaction(this); 
      T result; 
      try { 
        //1.执行业务逻辑 
         result = action.doInTransaction(status); 
      } 
      // 2.异常则回退 
      catch (RuntimeException ex) { 
         // Transactional code threw application exception -> rollback 
         rollbackOnException(status, ex); 
         throw ex; 
      } 
      catch (Error err) { 
         // Transactional code threw error -> rollback 
         rollbackOnException(status, err); 
         throw err; 
      } 
      catch (Exception ex) { 
         // Transactional code threw unexpected exception -> rollback 
         rollbackOnException(status, ex); 
         throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception"); 
      } 
      // 3.没有异常事务提交 
      this.transactionManager.commit(status); 
      return result; 
   } 
} 
 
   private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException { 
      logger.debug("Initiating transaction rollback on application exception", ex); 
      try { 
         this.transactionManager.rollback(status); 
      } 
      catch (TransactionSystemException ex2) { 
         logger.error("Application exception overridden by rollback exception", ex); 
         ex2.initApplicationException(ex); 
         throw ex2; 
      } 
      catch (RuntimeException ex2) { 
         logger.error("Application exception overridden by rollback exception", ex); 
         throw ex2; 
      } 
      catch (Error err) { 
         logger.error("Application exception overridden by rollback error", ex); 
         throw err; 
      } 
   } 
 
}
0,获取一个事务状态
this.transactionManager.getTransaction(this);
这里的transactionManager就是前面使用代码的配置中txManager,就是DataSourceTransactionManager,模版类AbstractPlatformTransactionManager。而传参this就是DefaultTransactionDefinition。
下面是AbstractPlatformTransactionManager里的模版方法:
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { 
   // 进来就先获取事务 
   Object transaction = doGetTransaction(); 
 
   // Cache debug flag to avoid repeated checks. 
   // 这里为打日志判断日志级别做的优化,这个在http://www.cnblogs.com/killbug/p/6721047.html 最后有解释。 
   boolean debugEnabled = logger.isDebugEnabled(); 
 
   if (definition == null) { 
      // Use defaults if no transaction definition given. 
      definition = new DefaultTransactionDefinition(); 
   } 
 
   if (isExistingTransaction(transaction)) { 
      // Existing transaction found -> check propagation behavior to find out how to behave. 
      return handleExistingTransaction(definition, transaction, debugEnabled); 
   } 
 
   // Check definition settings for new transaction. 
   if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { 
      throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); 
   } 
 
   // No existing transaction found -> check propagation behavior to find out how to proceed. 
   // 配置了PROPAGATION_MANDATORY就不能调用这个方法的,这个方法是开始获取事务的地方 
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { 
      throw new IllegalTransactionStateException( 
            "No existing transaction found for transaction marked with propagation 'mandatory'"); 
   } 
   else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || 
         definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || 
         definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { 
      // 外层挂起事务时保存的资源 
      SuspendedResourcesHolder suspendedResources = suspend(null); 
      if (debugEnabled) { 
         logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition); 
      } 
      try { 
         boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); 
         // 新建事务 
         DefaultTransactionStatus status = newTransactionStatus( 
               definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); 
         doBegin(transaction, definition); 
         prepareSynchronization(status, definition); 
         return status; 
      } 
      catch (RuntimeException ex) { 
         resume(null, suspendedResources); 
         throw ex; 
      } 
      catch (Error err) { 
         resume(null, suspendedResources); 
         throw err; 
      } 
   } 
   else { 
      // Create "empty" transaction: no actual transaction, but potentially synchronization. 
      if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) { 
         logger.warn("Custom isolation level specified but no actual transaction initiated; " + 
               "isolation level will effectively be ignored: " + definition); 
      } 
      boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); 
      return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null); 
   } 
}

1,回滚代码:

private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException { 
   logger.debug("Initiating transaction rollback on application exception", ex); 
   try { 
      this.transactionManager.rollback(status); 
   } 
   catch (TransactionSystemException ex2) { 
      logger.error("Application exception overridden by rollback exception", ex); 
      ex2.initApplicationException(ex); 
      throw ex2; 
   } 
   catch (RuntimeException ex2) { 
      logger.error("Application exception overridden by rollback exception", ex); 
      throw ex2; 
   } 
   catch (Error err) { 
      logger.error("Application exception overridden by rollback error", ex); 
      throw err; 
   } 
}

transactionManager.rollback

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); 
} 
//模版方法 子类实现自己的会滚操作 
private void processRollback(DefaultTransactionStatus status) { 
   try { 
      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 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"); 
         } 
      } 
      catch (RuntimeException ex) { 
         triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); 
         throw ex; 
      } 
      catch (Error err) { 
         triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); 
         throw err; 
      } 
      triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); 
   } 
   finally { 
      cleanupAfterCompletion(status); 
   } 
}

事务提交:

// 模版 
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); 
      return; 
   } 
   if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) { 
      if (defStatus.isDebug()) { 
         logger.debug("Global transaction is marked as rollback-only but transactional code requested commit"); 
      } 
      processRollback(defStatus); 
      // Throw UnexpectedRollbackException only at outermost transaction boundary 
      // or if explicitly asked to. 
      if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) { 
         throw new UnexpectedRollbackException( 
               "Transaction rolled back because it has been marked as rollback-only"); 
      } 
      return; 
   } 
 
   processCommit(defStatus); 
}

AbstractPlatformTransactionManager做为模版类,代码清晰。

我们发现在上面的execute,异常会退时是不没有任何区分什么异常会滚,什么异常不会滚,都是走rollbackOnException。其实我们只要在业务方法中把异常吃掉即可,另外对于回滚后异常抛出,在最外层再把异常做处理。

本篇没有真正深入了解原理实现,写在这里是为了开个头。


声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

我的关注

全民解析

搜索
排行榜
关注我们