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

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

  • 相关阅读:
    对于WP你所要了解的一些数字
    Win8系统太难用,再也不用了
    WP8下一些图片图标的常识(菜鸟篇)
    Wp8程序加载运行顺序(菜鸟篇)
    DLNA介绍(包括UPnP)
    一个通用的WPF值转换器
    C#创建Windows服务
    Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 数据访问层
    Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 1准备
    ASP.NET MVC Localization Helpers (本地化帮助方法)
  • 原文地址:https://www.cnblogs.com/killbug/p/6817338.html
Copyright © 2020-2023  润新知