`
huibin
  • 浏览: 740502 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Spring源代码解析(六):Spring声明式事务处理

阅读更多

我们看看Spring中的事务处理的代码,使用Spring管理事务有声明式和编程式两种方式,声明式事务处理通过AOP的实现把事物管理代码作为 方面封装来横向插入到业务代码中,使得事务管理代码和业务代码解藕。在这种方式我们结合IoC容器和Spirng已有的FactoryBean来对事务管 理进行属性配置,比如传播行为,隔离级别等。其中最简单的方式就是通过配置TransactionProxyFactoryBean来实现声明式事物;
在 整个源代码分析中,我们可以大致可以看到Spring实现声明式事物管理有这么几个部分:

    * 对在上下文中配置的属性的处理,这里涉及的类是TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进 行处理,属性信息放在TransactionAttribute中来使用,而这些属性的处理往往是和对切入点的处理是结合起来的。对属性的处理放在类 TransactionAttributeSource中完成。
    * 创建事物的过程,这个过程是委托给具体的事物管理器来创建的,但Spring通过TransactionStatus来传递相关的信息。
    * 对事物的处理通过对相关信息的判断来委托给具体的事物管理器完成。

我们下面看看具体的实现,在 TransactionFactoryBean中:

Java代码 复制代码
  1. public   class  TransactionProxyFactoryBean  extends  AbstractSingletonProxyFactoryBean   
  2.          implements  FactoryBean, BeanFactoryAware {   
  3. //这里是Spring事务处理而使用的AOP拦截器,中间封装了Spring对事务处理的代码来 支持声明式事务处理的实现   
  4.      private   final  TransactionInterceptor transactionInterceptor =  new  TransactionInterceptor();   
  5.   
  6.      private  Pointcut pointcut;   
  7.   
  8. //这里Spring把TransactionManager注入到 TransactionInterceptor中去   
  9.      public   void  setTransactionManager(PlatformTransactionManager transactionManager) {   
  10.          this .transactionInterceptor.setTransactionManager(transactionManager);   
  11.     }   
  12.   
  13. //这里把在bean配置文件中读到的事务管理的属性信息注入到 TransactionInterceptor中去   
  14.      public   void  setTransactionAttributes(Properties transactionAttributes) {   
  15.          this .transactionInterceptor.setTransactionAttributes(transactionAttributes);   
  16.     }   
  17.   
  18.     .........中间省略了其他一些方法.......   
  19.   
  20.      //这里创建Spring AOP对事务处理的Advisor   
  21.      protected  Object createMainInterceptor() {   
  22.          this .transactionInterceptor.afterPropertiesSet();   
  23.          if  ( this .pointcut !=  null ) {   
  24.              //这里使用默认的通知器   
  25.              return   new  DefaultPointcutAdvisor( this .pointcut,  this .transactionInterceptor);   
  26.         }   
  27.          else  {   
  28.              // 使用上面定义好的 TransactionInterceptor作为拦截器,同时使用TransactionAttributeSourceAdvisor   
  29.              return   new  TransactionAttributeSourceAdvisor( this .transactionInterceptor);   
  30.         }   
  31.     }   
  32. }  
public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean
        implements FactoryBean, BeanFactoryAware {
//这里是Spring事务处理而使用的AOP拦截器,中间封装了Spring对事务处理的代码来支持声明式事务处理的实现
    private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();

    private Pointcut pointcut;

//这里Spring把TransactionManager注入到TransactionInterceptor中去
    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionInterceptor.setTransactionManager(transactionManager);
    }

//这里把在bean配置文件中读到的事务管理的属性信息注入到TransactionInterceptor中去
    public void setTransactionAttributes(Properties transactionAttributes) {
        this.transactionInterceptor.setTransactionAttributes(transactionAttributes);
    }

    .........中间省略了其他一些方法.......

    //这里创建Spring AOP对事务处理的Advisor
    protected Object createMainInterceptor() {
        this.transactionInterceptor.afterPropertiesSet();
        if (this.pointcut != null) {
            //这里使用默认的通知器
            return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);
        }
        else {
            // 使用上面定义好的TransactionInterceptor作为拦截器,同时使用TransactionAttributeSourceAdvisor
            return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);
        }
    }
}


那什么时候Spring的TransactionInterceptor被注入到Spring AOP中成为Advisor中的一部分呢?我们看到在TransactionProxyFactoryBean中,这个方法在IOC初始化bean的时候 被执行:

Java代码 复制代码
  1. public   void  afterPropertiesSet() {   
  2.     .......   
  3.      //TransactionProxyFactoryBean 实际上使用ProxyFactory完成AOP的基本功能。   
  4.     ProxyFactory proxyFactory =  new  ProxyFactory();   
  5.   
  6.      if  ( this .preInterceptors !=  null ) {   
  7.          for  ( int  i =  0 ; i <  this .preInterceptors.length; i++) {   
  8.             proxyFactory.addAdvisor( this .advisorAdapterRegistry.wrap( this .preInterceptors[i]));   
  9.         }   
  10.     }   
  11.   
  12.      //这里是Spring加入通知器的地方   
  13.      //有两种通知器可以被加入 DefaultPointcutAdvisor或者TransactionAttributeSourceAdvisor   
  14.      //这里把Spring处理声明式事务处理的AOP代码都放到 ProxyFactory中去,怎样加入advisor我们可以参考ProxyFactory的父类AdvisedSupport()   
  15.      //由它来维护一个advice的链表,通过这个链表的增删改 来抽象我们对整个通知器配置的增删改操作。   
  16.     proxyFactory.addAdvisor( this .advisorAdapterRegistry.wrap(createMainInterceptor()));   
  17.   
  18.      if  ( this .postInterceptors !=  null ) {   
  19.          for  ( int  i =  0 ; i <  this .postInterceptors.length; i++) {   
  20.             proxyFactory.addAdvisor( this .advisorAdapterRegistry.wrap( this .postInterceptors[i]));   
  21.         }   
  22.     }   
  23.   
  24.     proxyFactory.copyFrom( this );   
  25.       
  26.      //这里创建AOP的目标源   
  27.     TargetSource targetSource = createTargetSource( this .target);   
  28.     proxyFactory.setTargetSource(targetSource);   
  29.   
  30.      if  ( this .proxyInterfaces !=  null ) {   
  31.         proxyFactory.setInterfaces( this .proxyInterfaces);   
  32.     }   
  33.      else   if  (!isProxyTargetClass()) {   
  34.         proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass()));   
  35.     }   
  36.   
  37.      this .proxy = getProxy(proxyFactory);   
  38. }  
    public void afterPropertiesSet() {
        .......
        //TransactionProxyFactoryBean实际上使用ProxyFactory完成AOP的基本功能。
        ProxyFactory proxyFactory = new ProxyFactory();

        if (this.preInterceptors != null) {
            for (int i = 0; i < this.preInterceptors.length; i++) {
                proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.preInterceptors[i]));
            }
        }

        //这里是Spring加入通知器的地方
        //有两种通知器可以被加入DefaultPointcutAdvisor或者TransactionAttributeSourceAdvisor
        //这里把Spring处理声明式事务处理的AOP代码都放到ProxyFactory中去,怎样加入advisor我们可以参考ProxyFactory的父类AdvisedSupport()
        //由它来维护一个advice的链表,通过这个链表的增删改来抽象我们对整个通知器配置的增删改操作。
        proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));

        if (this.postInterceptors != null) {
            for (int i = 0; i < this.postInterceptors.length; i++) {
                proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.postInterceptors[i]));
            }
        }

        proxyFactory.copyFrom(this);
       
        //这里创建AOP的目标源
        TargetSource targetSource = createTargetSource(this.target);
        proxyFactory.setTargetSource(targetSource);

        if (this.proxyInterfaces != null) {
            proxyFactory.setInterfaces(this.proxyInterfaces);
        }
        else if (!isProxyTargetClass()) {
            proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass()));
        }

        this.proxy = getProxy(proxyFactory);
    }


Spring 已经定义了一个transctionInterceptor作为拦截器或者AOP advice的实现,在IOC容器中定义的其他属性比如transactionManager和事务管理的属性都会传到已经定义好的 TransactionInterceptor那里去进行处理。以上反映了基本的Spring AOP的定义过程,其中pointcut和advice都已经定义好,同时也通过通知器配置到ProxyFactory中去了。
下面让我们回到 TransactionProxyFactoryBean中看看TransactionAttributeSourceAdvisor是怎样定义的,这样 我们可以理解具体的属性是怎样起作用,这里我们分析一下类TransactionAttributeSourceAdvisor:

Java代码 复制代码
  1. public   class  TransactionAttributeSourceAdvisor  extends  AbstractPointcutAdvisor {   
  2.      //和其他Advisor一样,同样需要定义AOP中的用到的 Interceptor和Pointcut   
  3.      //Interceptor使用传进来的 TransactionInterceptor   
  4.      //而对于pointcut,这里定义了一个内部类,参见下面 的代码     
  5.      private  TransactionInterceptor transactionInterceptor;   
  6.   
  7.      private   final  TransactionAttributeSourcePointcut pointcut =  new  TransactionAttributeSourcePointcut();   
  8.       
  9.     .........   
  10.      //定义的PointCut内部类   
  11.          private   class  TransactionAttributeSourcePointcut  extends  StaticMethodMatcherPointcut  implements  Serializable {   
  12.        .......   
  13.        //方法匹配的实现,使用了 TransactionAttributeSource类   
  14.          public   boolean  matches(Method method, Class targetClass) {   
  15.             TransactionAttributeSource tas = getTransactionAttributeSource();   
  16.              //这里使用 TransactionAttributeSource来对配置属性进行处理   
  17.              return  (tas !=  null  && tas.getTransactionAttribute(method, targetClass) !=  null );   
  18.         }   
  19.     ........省略了equal,hashcode,tostring的代码   
  20.     }  
public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor {
    //和其他Advisor一样,同样需要定义AOP中的用到的Interceptor和Pointcut
    //Interceptor使用传进来的TransactionInterceptor
    //而对于pointcut,这里定义了一个内部类,参见下面的代码  
    private TransactionInterceptor transactionInterceptor;

    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut();
   
    .........
    //定义的PointCut内部类
        private class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
       .......
      //方法匹配的实现,使用了TransactionAttributeSource类
        public boolean matches(Method method, Class targetClass) {
            TransactionAttributeSource tas = getTransactionAttributeSource();
            //这里使用TransactionAttributeSource来对配置属性进行处理
            return (tas != null && tas.getTransactionAttribute(method, targetClass) != null);
        }
    ........省略了equal,hashcode,tostring的代码
    }


这里我们看看属性值是怎样被读入的:AbstractFallbackTransactionAttributeSource负责具体的属 性读入任务,我们可以有两种读入方式,比如annotation和直接配置.我们下面看看直接配置的读入方式,在Spring中同时对读入的属性值进行了 缓存处理,这是一个decorator模式:

Java代码 复制代码
  1. public   final  TransactionAttribute getTransactionAttribute(Method method, Class targetClass) {   
  2.      //这里先查一下缓存里有没有事务管理的属性配置,如果有从缓 存中取得TransactionAttribute   
  3.     Object cacheKey = getCacheKey(method, targetClass);   
  4.     Object cached =  this .cache.get(cacheKey);   
  5.      if  (cached !=  null ) {   
  6.          if  (cached == NULL_TRANSACTION_ATTRIBUTE) {   
  7.              return   null ;   
  8.         }   
  9.          else  {   
  10.              return  (TransactionAttribute) cached;   
  11.         }   
  12.     }   
  13.      else  {   
  14.          // 这里通过对方法和目标对象的信息来计算事务缓存 属性   
  15.         TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass);   
  16.          //把得到的事务缓存属性存到缓存中,下次可以直接从 缓存中取得。   
  17.          if  (txAtt ==  null ) {   
  18.              this .cache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);   
  19.         }   
  20.          else  {   
  21.             ...........   
  22.              this .cache.put(cacheKey, txAtt);   
  23.         }   
  24.          return  txAtt;   
  25.     }   
  26. }  
    public final TransactionAttribute getTransactionAttribute(Method method, Class targetClass) {
        //这里先查一下缓存里有没有事务管理的属性配置,如果有从缓存中取得TransactionAttribute
        Object cacheKey = getCacheKey(method, targetClass);
        Object cached = this.cache.get(cacheKey);
        if (cached != null) {
            if (cached == NULL_TRANSACTION_ATTRIBUTE) {
                return null;
            }
            else {
                return (TransactionAttribute) cached;
            }
        }
        else {
            // 这里通过对方法和目标对象的信息来计算事务缓存属性
            TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass);
            //把得到的事务缓存属性存到缓存中,下次可以直接从缓存中取得。
            if (txAtt == null) {
                this.cache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
            }
            else {
                ...........
                this.cache.put(cacheKey, txAtt);
            }
            return txAtt;
        }
    }


别急,基本的处理在computeTransactionAttribute()中:

Java代码 复制代码
  1. private  TransactionAttribute computeTransactionAttribute(Method method, Class targetClass) {   
  2.      //这里检测是不是public方法   
  3.      if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {   
  4.          return   null ;   
  5.     }   
  6.       
  7.     Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);   
  8.       
  9.      // First try is the method in the target class.   
  10.     TransactionAttribute txAtt = findTransactionAttribute(findAllAttributes(specificMethod));   
  11.      if  (txAtt !=  null ) {   
  12.          return  txAtt;   
  13.     }   
  14.   
  15.      // Second try is the transaction attribute on the target class.   
  16.     txAtt = findTransactionAttribute(findAllAttributes(specificMethod.getDeclaringClass()));   
  17.      if  (txAtt !=  null ) {   
  18.          return  txAtt;   
  19.     }   
  20.   
  21.      if  (specificMethod != method) {   
  22.          // Fallback is to look at the original method.   
  23.         txAtt = findTransactionAttribute(findAllAttributes(method));   
  24.          if  (txAtt !=  null ) {   
  25.              return  txAtt;   
  26.         }   
  27.          // Last fallback is the class of the original method.   
  28.          return  findTransactionAttribute(findAllAttributes(method.getDeclaringClass()));   
  29.     }   
  30.      return   null ;   
  31. }  
    private TransactionAttribute computeTransactionAttribute(Method method, Class targetClass) {
        //这里检测是不是public方法
        if(allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
            return null;
        }
       
        Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
       
        // First try is the method in the target class.
        TransactionAttribute txAtt = findTransactionAttribute(findAllAttributes(specificMethod));
        if (txAtt != null) {
            return txAtt;
        }

        // Second try is the transaction attribute on the target class.
        txAtt = findTransactionAttribute(findAllAttributes(specificMethod.getDeclaringClass()));
        if (txAtt != null) {
            return txAtt;
        }

        if (specificMethod != method) {
            // Fallback is to look at the original method.
            txAtt = findTransactionAttribute(findAllAttributes(method));
            if (txAtt != null) {
                return txAtt;
            }
            // Last fallback is the class of the original method.
            return findTransactionAttribute(findAllAttributes(method.getDeclaringClass()));
        }
        return null;
    }


经过一系列的尝试我们可以通过findTransactionAttribute()通过调用findAllAttribute()得到 TransactionAttribute的对象,如果返回的是null,这说明该方法不是我们需要事务处理的方法。
在完成把需要的通知器加到 ProxyFactory中去的基础上,我们看看具体的看事务处理代码怎样起作用,在TransactionInterceptor中:

Java代码 复制代码
  1. public  Object invoke( final  MethodInvocation invocation)  throws  Throwable {   
  2.      //这里得到目标对象   
  3.     Class targetClass = (invocation.getThis() !=  null  ? invocation.getThis().getClass() :  null );   
  4.   
  5.      //这里同样的通过判断是否能够得到 TransactionAttribute来决定是否对当前方法进行事务处理,有可能该属性已经被缓存,   
  6.      //具体可以参考上面对 getTransactionAttribute的分析,同样是通过TransactionAttributeSource   
  7.      final  TransactionAttribute txAttr =   
  8.             getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);   
  9.      final  String joinpointIdentification = methodIdentification(invocation.getMethod());   
  10.   
  11.      //这里判断我们使用了什么 TransactionManager   
  12.      if  (txAttr ==  null  || !(getTransactionManager()  instanceof  CallbackPreferringPlatformTransactionManager)) {   
  13.          // 这里创建事务,同时把创建事务过程中得到的信息 放到TransactionInfo中去   
  14.         TransactionInfo txInfo = createTransactionIfNecessary(txAttr, joinpointIdentification);   
  15.         Object retVal =  null ;   
  16.          try  {   
  17.               retVal = invocation.proceed();   
  18.         }   
  19.          catch  (Throwable ex) {   
  20.              // target invocation exception   
  21.             completeTransactionAfterThrowing(txInfo, ex);   
  22.              throw  ex;   
  23.         }   
  24.          finally  {   
  25.             cleanupTransactionInfo(txInfo);   
  26.         }   
  27.         commitTransactionAfterReturning(txInfo);   
  28.          return  retVal;   
  29.     }   
  30.   
  31.      else  {   
  32.          // 使用的是Spring定义的 PlatformTransactionManager同时实现了回调接口,我们通过其回调函数完成事务处理,就像我们使用编程式事务处理一样。   
  33.          try  {   
  34.             Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,   
  35.                      new  TransactionCallback() {   
  36.                          public  Object doInTransaction(TransactionStatus status) {   
  37.                              //同样的 需要一个TransactonInfo   
  38.                             TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);   
  39.                              try  {   
  40.                                  return  invocation.proceed();   
  41.                             }   
  42.                          .....这里省去了异常处理和事务信息的清理代码   
  43.                     });   
  44.          ...........   
  45.     }   
  46. }  
    public Object invoke(final MethodInvocation invocation) throws Throwable {
        //这里得到目标对象
        Class targetClass = (invocation.getThis() != null ? invocation.getThis().getClass() : null);

        //这里同样的通过判断是否能够得到TransactionAttribute来决定是否对当前方法进行事务处理,有可能该属性已经被缓存,
        //具体可以参考上面对getTransactionAttribute的分析,同样是通过TransactionAttributeSource
        final TransactionAttribute txAttr =
                getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
        final String joinpointIdentification = methodIdentification(invocation.getMethod());

        //这里判断我们使用了什么TransactionManager
        if (txAttr == null || !(getTransactionManager() instanceof CallbackPreferringPlatformTransactionManager)) {
            // 这里创建事务,同时把创建事务过程中得到的信息放到TransactionInfo中去
            TransactionInfo txInfo = createTransactionIfNecessary(txAttr, joinpointIdentification);
            Object retVal = null;
            try {
                  retVal = invocation.proceed();
            }
            catch (Throwable ex) {
                // target invocation exception
                completeTransactionAfterThrowing(txInfo, ex);
                throw ex;
            }
            finally {
                cleanupTransactionInfo(txInfo);
            }
            commitTransactionAfterReturning(txInfo);
            return retVal;
        }

        else {
            // 使用的是Spring定义的PlatformTransactionManager同时实现了回调接口,我们通过其回调函数完成事务处理,就像我们使用编程式事务处理一样。
            try {
                Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,
                        new TransactionCallback() {
                            public Object doInTransaction(TransactionStatus status) {
                                //同样的需要一个TransactonInfo
                                TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);
                                try {
                                    return invocation.proceed();
                                }
                             .....这里省去了异常处理和事务信息的清理代码
                        });
             ...........
        }
    }


这里面涉及到事务的创建,我们可以在TransactionAspectSupport实现的事务管理代码:

Java代码 复制代码
  1. protected  TransactionInfo createTransactionIfNecessary(   
  2.         TransactionAttribute txAttr,  final  String joinpointIdentification) {   
  3.   
  4.      // If no name specified, apply method identification as transaction name.   
  5.      if  (txAttr !=  null  && txAttr.getName() ==  null ) {   
  6.         txAttr =  new  DelegatingTransactionAttribute(txAttr) {   
  7.              public  String getName() {   
  8.                  return  joinpointIdentification;   
  9.             }   
  10.         };   
  11.     }   
  12.   
  13.     TransactionStatus status =  null ;   
  14.      if  (txAttr !=  null ) {   
  15.      //这里使用了我们定义好的事务配置信息,有事务管理器来创建 事务,同时返回TransactionInfo   
  16.         status = getTransactionManager().getTransaction(txAttr);   
  17.     }   
  18.      return  prepareTransactionInfo(txAttr, joinpointIdentification, status);   
  19. }  
    protected TransactionInfo createTransactionIfNecessary(
            TransactionAttribute txAttr, final String joinpointIdentification) {

        // If no name specified, apply method identification as transaction name.
        if (txAttr != null && txAttr.getName() == null) {
            txAttr = new DelegatingTransactionAttribute(txAttr) {
                public String getName() {
                    return joinpointIdentification;
                }
            };
        }

        TransactionStatus status = null;
        if (txAttr != null) {
        //这里使用了我们定义好的事务配置信息,有事务管理器来创建事务,同时返回TransactionInfo
            status = getTransactionManager().getTransaction(txAttr);
        }
        return prepareTransactionInfo(txAttr, joinpointIdentification, status);
    }


首先通过TransactionManager得到需要的事务,事务的创建根据我们定义的事务配置决定,在 AbstractTransactionManager中给出一个标准的创建过程,当然创建什么样的事务还是需要具体的 PlatformTransactionManager来决定,但这里给出了创建事务的模板:

Java代码 复制代码
  1. public   final  TransactionStatus getTransaction(TransactionDefinition definition)  throws  TransactionException {   
  2.     Object transaction = doGetTransaction();   
  3.     ......   
  4.   
  5.      if  (definition ==  null ) {   
  6.          //如果事务信息没有被配置,我们使用Spring默 认的配置方式   
  7.         definition =  new  DefaultTransactionDefinition();   
  8.     }   
  9.   
  10.      if  (isExistingTransaction(transaction)) {   
  11.          // Existing transaction found -> check propagation behavior to find out how to behave.   
  12.          return  handleExistingTransaction(definition, transaction, debugEnabled);   
  13.     }   
  14.   
  15.      // Check definition settings for new transaction.   
  16.      //下面就是使用配置信息来创建我们需要的事务;比如传播属性 和同步属性等   
  17.      //最后把创建过程中的信息收集起来放到 TransactionStatus中返回;     
  18.      if  (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {   
  19.          throw   new  InvalidTimeoutException( "Invalid transaction timeout" , definition.getTimeout());   
  20.     }   
  21.   
  22.      // No existing transaction found -> check propagation behavior to find out how to behave.   
  23.      if  (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {   
  24.          throw   new  IllegalTransactionStateException(   
  25.                  "Transaction propagation 'mandatory' but no existing transaction found" );   
  26.     }   
  27.      else   if  (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||   
  28.             definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||   
  29.         definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {   
  30.          //这里是事务管理器创建事务的地方,并将创建过程中 得到的信息放到TransactionStatus中去,包括创建出来的事务   
  31.         doBegin(transaction, definition);   
  32.          boolean  newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);   
  33.          return  newTransactionStatus(definition, transaction,  true , newSynchronization, debugEnabled,  null );   
  34.     }   
  35.      else  {   
  36.          boolean  newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);   
  37.          return  newTransactionStatus(definition,  null false , newSynchronization, debugEnabled,  null );   
  38.     }   
  39. }  
    public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        Object transaction = doGetTransaction();
        ......

        if (definition == null) {
            //如果事务信息没有被配置,我们使用Spring默认的配置方式
            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.
        //下面就是使用配置信息来创建我们需要的事务;比如传播属性和同步属性等
        //最后把创建过程中的信息收集起来放到TransactionStatus中返回;  
        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 behave.
        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
            throw new IllegalTransactionStateException(
                    "Transaction propagation 'mandatory' but no existing transaction found");
        }
        else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
                definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
            definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
            //这里是事务管理器创建事务的地方,并将创建过程中得到的信息放到TransactionStatus中去,包括创建出来的事务
            doBegin(transaction, definition);
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
        }
        else {
            boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
            return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null);
        }
    }


接着通过调用prepareTransactionInfo完成事务创建的准备,创建过程中得到的信息存储在 TransactionInfo对象中进行传递同时把信息和当前线程绑定;

Java代码 复制代码
  1. protected  TransactionInfo prepareTransactionInfo(   
  2.         TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {   
  3.   
  4.     TransactionInfo txInfo =  new  TransactionInfo(txAttr, joinpointIdentification);   
  5.      if  (txAttr !=  null ) {   
  6.     .....   
  7.          // 同样的需要把在getTransaction中 得到的TransactionStatus放到TransactionInfo中来。   
  8.         txInfo.newTransactionStatus(status);   
  9.     }   
  10.      else  {   
  11.     .......   
  12.    }   
  13.   
  14.      // 绑定事务创建信息到当前线程   
  15.     txInfo.bindToThread();   
  16.      return  txInfo;   
  17. }  
    protected TransactionInfo prepareTransactionInfo(
            TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {

        TransactionInfo txInfo = new TransactionInfo(txAttr, joinpointIdentification);
        if (txAttr != null) {
        .....
            // 同样的需要把在getTransaction中得到的TransactionStatus放到TransactionInfo中来。
            txInfo.newTransactionStatus(status);
        }
        else {
        .......
       }

        // 绑定事务创建信息到当前线程
        txInfo.bindToThread();
        return txInfo;
    }


将创建事务的信息返回,然后看到其他的事务管理代码:

Java代码 复制代码
  1. protected   void  commitTransactionAfterReturning(TransactionInfo txInfo) {   
  2.      if  (txInfo !=  null  && txInfo.hasTransaction()) {   
  3.          if  (logger.isDebugEnabled()) {   
  4.             logger.debug( "Invoking commit for transaction on "  + txInfo.getJoinpointIdentification());   
  5.         }   
  6.          this .transactionManager.commit(txInfo.getTransactionStatus());   
  7.     }   
  8. }  
    protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
        if (txInfo != null && txInfo.hasTransaction()) {
            if (logger.isDebugEnabled()) {
                logger.debug("Invoking commit for transaction on " + txInfo.getJoinpointIdentification());
            }
            this.transactionManager.commit(txInfo.getTransactionStatus());
        }
    }


通过transactionManager对事务进行处理,包括异常抛出和正常的提交事务,具体的事务管理器由用户程序设定。

Java代码 复制代码
  1. protected   void  completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {   
  2.      if  (txInfo !=  null  && txInfo.hasTransaction()) {   
  3.          if  (txInfo.transactionAttribute.rollbackOn(ex)) {   
  4.             ......   
  5.              try  {   
  6.                  this .transactionManager.rollback(txInfo.getTransactionStatus());   
  7.             }   
  8.             ..........   
  9.   }   
  10.          else  {   
  11.             .........   
  12.              try  {   
  13.                  this .transactionManager.commit(txInfo.getTransactionStatus());   
  14.             }   
  15.    ...........   
  16. }   
  17.   
  18. protected   void  commitTransactionAfterReturning(TransactionInfo txInfo) {   
  19.      if  (txInfo !=  null  && txInfo.hasTransaction()) {   
  20.         ......   
  21.          this .transactionManager.commit(txInfo.getTransactionStatus());   
  22.     }   
  23. }  
    protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
        if (txInfo != null && txInfo.hasTransaction()) {
            if (txInfo.transactionAttribute.rollbackOn(ex)) {
                ......
                try {
                    this.transactionManager.rollback(txInfo.getTransactionStatus());
                }
                ..........
      }
            else {
                .........
                try {
                    this.transactionManager.commit(txInfo.getTransactionStatus());
                }
       ...........
    }

    protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
        if (txInfo != null && txInfo.hasTransaction()) {
            ......
            this.transactionManager.commit(txInfo.getTransactionStatus());
        }
    }


Spring通过以上代码对transactionManager进行事务处理的过程进行了AOP包装,到这里我们看到为了方便客户实现声 明式的事务处理,Spring还是做了许多工作的。如果说使用编程式事务处理,过程其实比较清楚,我们可以参考书中的例子:

Java代码 复制代码
  1. TransactionDefinition td =  new  DefaultTransactionDefinition();   
  2. TransactionStatus status = transactionManager.getTransaction(td);   
  3. try {   
  4.       ...... //这里是我们的业务方法   
  5. } catch  (ApplicationException e) {   
  6.    transactionManager.rollback(status);   
  7.     throw  e   
  8. }   
  9. transactionManager.commit(status);   
  10.  ........  
    TransactionDefinition td = new DefaultTransactionDefinition();
    TransactionStatus status = transactionManager.getTransaction(td);
    try{
          ......//这里是我们的业务方法
    }catch (ApplicationException e) {
       transactionManager.rollback(status);
       throw e
    }
    transactionManager.commit(status);
     ........


我们看到这里选取了默认的事务配置DefaultTransactionDefinition,同时在创建事物的过程中得到 TransactionStatus,然后通过直接调用事务管理器的相关方法就能完成事务处理。
声明式事务处理也同样实现了类似的过程,只是因 为采用了声明的方法,需要增加对属性的读取处理,并且需要把整个过程整合到Spring AOP框架中和IoC容器中去的过程。
下面我们选取一 个具体的transactionManager - DataSourceTransactionManager来看看其中事务处理的实现:
同 样的通过使用AbstractPlatformTransactionManager使用模板方法,这些都体现了对具体平台相关的事务管理器操作的封装, 比如commit:

Java代码 复制代码
  1. public   final   void  commit(TransactionStatus status)  throws  TransactionException {   
  2.     ......   
  3.     DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;   
  4.      if  (defStatus.isLocalRollbackOnly()) {   
  5.         ......   
  6.         processRollback(defStatus);   
  7.          return ;   
  8.     }   
  9.          .......   
  10.         processRollback(defStatus);   
  11.     ......   
  12.     }   
  13.   
  14.     processCommit(defStatus);   
  15. }  
    public final void commit(TransactionStatus status) throws TransactionException {
        ......
        DefaultTransactionStatus defStatus = (DefaultT

  


  
分享到:
评论

相关推荐

    Spring源代码解析.rar

    Spring源代码解析6:Spring声明式事务处理 .doc Spring源代码解析7:Spring AOP中对拦截器调用的实现 .doc Spring源代码解析8:Spring驱动Hibernate的实现.doc Spring源代码解析9:Spring Acegi框架鉴权的实现.doc ...

    Spring 源代码解析

    Spring源代码解析6:Spring声明式事务处理 ; Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代码解析9:Spring Acegi框架鉴权的实现 Spring源...

    Spring源代码解析(六):Spring声明式事务处理.doc

    Spring源代码解析(六):Spring声明式事务处理.doc

    Spring源代码解析

    Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 ...

    springyuanmaaping.zip

    pring源代码解析1:IOC容器;Spring源代码解析2:IoC...Spring源代码解析6:Spring声明式事务处理 ; Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代

    spring源码分析(1-10)

    Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 ...

    spring源码分析

    Spring源代码解析(六):Spring声明式事务处理 7. Spring源代码解析(七):Spring AOP中对拦截器调用的实现 8. Spring源代码解析(八):Spring驱动Hibernate的实现 9.Spring源代码解析(九):Spring Acegi...

    Spring源码学习文档,绝对值得好好研究~~

    Spring源代码解析(六):Spring声明式事务处理.doc Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的实现.doc Spring源代码解析(九):Spring Acegi...

    Spring+Hibernate 声明式事务

    本资源主要是结合博文 Spring+Hibernate: 声明式事务 http://blog.csdn.net/ManagementAndJava/article/details/78050519 的源代码,主要是讲解了spring4.3和hibernate5.2.11集成实现原理;

    Spring JDBC与事务管理源代码

    1、掌握Spring JDBC的配置; 2、掌握JdbcTemplae类中增删改查方法的使用; 3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式;...5、掌握基于XML和Annotation的声明式事务管理的使用。

    spring+hibernate学习笔记和项目源代码

    struts与hibernate集成原理,基础知识补充AOP,编程式事务,声明式事务,spring注入学习笔记

    跟我学Spring3(9.4)Spring的事务之声明式事

    跟我学Spring3(9.4)Spring的事务之声明式事务Java开发Java经验技巧共12页.pdf.zip

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.6.1. @Transactional 有关的设置 ...

    Spring 2.0 开发参考手册

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 插入事务操作 9.5.8. ...

    Spring中文帮助文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    Spring API

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    spring chm文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 插入事务操作 9.5.8. ...

    spring事务以及分布式事务实现.zip

    spring事务以及分布式事务实现.zip one-data-source 单数据源事务 two-data-source 多数据源事务 模块包括 多数据源配置方法 使用atomikos管理多数据源事务 多数据源事务结合Druid...代码包括声明式事务和编程式事务

    第24次课-1 Spring与Hibernate的整合

    方便的事务管理:Spring提供的声明式事务处理可以全面有效地处理事务。 异常包装:Spring能够包装Hibernate的异常,使开发者可以选择恰当的层来处理异常。 24.2 管理SessionFactory Hibernate的SessionFactory,是...

Global site tag (gtag.js) - Google Analytics