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

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。其实我们只要在业务方法中把异常吃掉即可,另外对于回滚后异常抛出,在最外层再把异常做处理。

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

posted on   每当变幻时  阅读(1681)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示