天天看点

Spring Tx (二) (事务案例及源码 1)

文章目录

  • ​​1.事务案例​​
  • ​​1.1 编程式事务管理​​
  • ​​1.2 申明式事务管理​​
  • ​​2.源码分析​​
  • ​​2.1 编程式事务TransactionTemplate​​
  • ​​2.2 申明式事务@Transactional​​
  • ​​2.2.1 AutoProxyRegistrar​​
  • ​​2.2.2 ProxyTransactionManagementConfiguration​​

1.事务案例

  1. 编程式事务管理: 编程式事务管理使用底层源码可实现更细粒度的事务控制。spring推荐使用TransactionTemplate,典型的模板模式。
  2. 申明式事务管理: 添加@Transactional注解,并定义传播机制+回滚策略。基于Spring AOP实现,本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
Spring Tx (二) (事务案例及源码 1)

TxConfig.java

@ComponentScan("com.atguigu.tx")
@EnableTransactionManagement
@Configuration
public class TxConfig {
    @Bean
    public DataSource dataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("root");
        druidDataSource.setUrl("jdbc:mysql:///test");
        return druidDataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        return jdbcTemplate;

    }

    @Bean
    public PlatformTransactionManager transactionManager(){
        return new DataSourceTransactionManager(dataSource());
    }
}      

UserDao.java

@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void insert(){
        String sql = "insert into user9 (name, age) values (?, ?)";
        String name = UUID.randomUUID().toString().substring(0, 5);
        jdbcTemplate.update(sql, name, 19);

    }
}      

MainApplication.java

public class MainApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class);
        UserService service = context.getBean(UserService.class);
        service.insertUser();
        context.close();
    }
}      

1.1 编程式事务管理

UserServiceTx.java

@Service
public class UserServiceTx {
    @Autowired
    private UserDao userDao;

    @Autowired
    private TransactionTemplate transactionTemplate;


    public void insertUser(){
        userDao.insert();
        int i = 10/0;
        System.out.println("ok");
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                // 业务
                try {
                    userDao.insert();
                } catch (Exception e) {
                    // 异常回滚
                    status.setRollbackOnly();
                }
            }
        });
    }
}      

1.2 申明式事务管理

UserService.java

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    @Transactional
    public void insertUser(){
        userDao.insert();
        int i = 10/0;
        System.out.println("ok");
    }

}      

务方法上添加@Transactional注解,定义事务的传播机制为REQUIRED(不写这个参数,默认就是REQUIRED), 存在加入事务,不存在创建新事务。

2.源码分析

2.1 编程式事务TransactionTemplate

Spring Tx (二) (事务案例及源码 1)
Spring Tx (二) (事务案例及源码 1)
public interface TransactionOperations {

    /**
     * Execute the action specified by the given callback object within a transaction.
     * <p>Allows for returning a result object created within the transaction, that is,
     * a domain object or a collection of domain objects. A RuntimeException thrown
     * by the callback is treated as a fatal exception that enforces a rollback.
     * Such an exception gets propagated to the caller of the template.
     * @param action the callback object that specifies the transactional action
     * @return a result object returned by the callback, or {@code null} if none
     * @throws TransactionException in case of initialization, rollback, or system errors
     * @throws RuntimeException if thrown by the TransactionCallback
     */
    <T> T execute(TransactionCallback<T> action) throws TransactionException;

}

public interface InitializingBean {

    /**
     * Invoked by a BeanFactory after it has set all bean properties supplied
     * (and satisfied BeanFactoryAware and ApplicationContextAware).
     * <p>This method allows the bean instance to perform initialization only
     * possible when all bean properties have been set and to throw an
     * exception in the event of misconfiguration.
     * @throws Exception in the event of misconfiguration (such
     * as failure to set an essential property) or if initialization fails.
     */
    void afterPropertiesSet() throws Exception;

}      
  • TransactionOperations: 执行事务的回调
  • InitializingBean: 加入容器的接口, 专用用来在bean属性加载完毕时执行的方法。
@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 {// 1.获取事务状态
            TransactionStatus status = this.transactionManager.getTransaction(this);
            T result;
            try {// 2.执行业务逻辑
                result = action.doInTransaction(status);
            }
            catch (RuntimeException ex) {
                // 应用运行时异常 -> 回滚
                rollbackOnException(status, ex);
                throw ex;
            }
            catch (Error err) {
                // Error异常 -> 回滚
                rollbackOnException(status, err);
                throw err;
            }
            catch (Throwable ex) {
                // 未知异常 -> 回滚
                rollbackOnException(status, ex);
                throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
            }// 3.事务提交
            this.transactionManager.commit(status);
            return result;
        }
    }      
  • getTransaction(): 获取事务
  • doInTransaction(): 执行业务逻辑
  • commit(): 提交事务, AbstractPlatformTransactionManager.commit()
  • rollbackOnException(): 异常回滚, AbstractPlatformTransactionManager.rollback()

2.2 申明式事务@Transactional

  1. 使用代理模式,生成代理增强类。
  2. 根据代理事务管理配置类,配置事务的织入,在业务方法前后进行环绕增强,增加一些事务的相关操作。例如获取事务属性、提交事务、回滚事务。
Spring Tx (二) (事务案例及源码 1)

springboot 容器启动时的自动配置载入, /META-INF/spring.factories中配置文件中查找

Spring Tx (二) (事务案例及源码 1)
  • TransactionAutoConfiguration
  • JtaAutoConfiguration

TransactionAutoConfiguration:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
    DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {

  @Bean
  @ConditionalOnMissingBean
  public TransactionManagerCustomizers platformTransactionManagerCustomizers(
      ObjectProvider<PlatformTransactionManagerCustomizer<?>> customizers) {
    return new TransactionManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
  }

  @Bean
  @ConditionalOnMissingBean
  @ConditionalOnSingleCandidate(ReactiveTransactionManager.class)
  public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {
    return TransactionalOperator.create(transactionManager);
  }

  @Configuration(proxyBeanMethods = false)
  @ConditionalOnSingleCandidate(PlatformTransactionManager.class)
  public static class TransactionTemplateConfiguration {

    @Bean
    @ConditionalOnMissingBean(TransactionOperations.class)
    public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
      return new TransactionTemplate(transactionManager);
    }

  }

  @Configuration(proxyBeanMethods = false)
  @ConditionalOnBean(TransactionManager.class)
  @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
  public static class EnableTransactionManagementConfiguration {

    @Configuration(proxyBeanMethods = false)
    @EnableTransactionManagement(proxyTargetClass = false)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
    public static class JdkDynamicAutoProxyConfiguration {

    }

    @Configuration(proxyBeanMethods = false)
    @EnableTransactionManagement(proxyTargetClass = true)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
        matchIfMissing = true)
    public static class CglibAutoProxyConfiguration {

    }

  }

}      
Spring Tx (二) (事务案例及源码 1)
Spring Tx (二) (事务案例及源码 1)
Spring Tx (二) (事务案例及源码 1)
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

  /**
   * Returns {@link ProxyTransactionManagementConfiguration} or
   * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
   * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
   * respectively.
   */
  @Override
  protected String[] selectImports(AdviceMode adviceMode) {
    switch (adviceMode) {
      case PROXY:
        return new String[] {AutoProxyRegistrar.class.getName(),
            ProxyTransactionManagementConfiguration.class.getName()};
      case ASPECTJ:
        return new String[] {determineTransactionAspectClass()};
      default:
        return null;
    }
  }

  private String determineTransactionAspectClass() {
    return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
        TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
        TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
  }

}      
  • AutoProxyRegistrar:给容器中注册一个 ​

    ​InfrastructureAdvisorAutoProxyCreator​

    ​ 组件;利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;
  • ProxyTransactionManagementConfiguration:定义了事务增强器, 负责注入事务相关的bean, 比如 ​

    ​BeanFactoryTransactionAttributeSourceAdvisor​

    ​​ 事务切面Bean, ​

    ​TransactionAttributeSource​

    ​​ 事务配置属性Bean, ​

    ​TransactionInterceptor​

    ​ 事务拦截器Bean.
2.2.1 AutoProxyRegistrar
Spring Tx (二) (事务案例及源码 1)
@Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    boolean candidateFound = false;
    Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
    for (String annType : annTypes) {
      AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
      if (candidate == null) {
        continue;
      }
      Object mode = candidate.get("mode");
      Object proxyTargetClass = candidate.get("proxyTargetClass");
      if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
          Boolean.class == proxyTargetClass.getClass()) {
        candidateFound = true;
        if (mode == AdviceMode.PROXY) {
          AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
          if ((Boolean) proxyTargetClass) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            return;
          }
        }
      }
    }
    if (!candidateFound && logger.isInfoEnabled()) {
      String name = getClass().getSimpleName();
      logger.info(String.format("%s was imported but no annotations were found " +
          "having both 'mode' and 'proxyTargetClass' attributes of type " +
          "AdviceMode and boolean respectively. This means that auto proxy " +
          "creator registration and configuration may not have occurred as " +
          "intended, and components may not be proxied as expected. Check to " +
          "ensure that %s has been @Import'ed on the same class where these " +
          "annotations are declared; otherwise remove the import of %s " +
          "altogether.", name, name, name));
    }
  }      

代理模式:AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);

Spring Tx (二) (事务案例及源码 1)

把InfrastructureAdvisorAutoProxyCreator注册beandefinition

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");       //如果当前注册器包含internalAutoProxyCreator
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {//org.springframework.aop.config.internalAutoProxyCreator内部自动代理构造器
            BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {//如果当前类不是internalAutoProxyCreator
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                if (currentPriority < requiredPriority) {//如果下标大于已存在的内部自动代理构造器,index越小,优先级越高,InfrastructureAdvisorAutoProxyCreator index=0,requiredPriority最小,不进入
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }
            return null;//直接返回
        }//如果当前注册器不包含internalAutoProxyCreator,则把当前类作为根定义
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);//优先级最高
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
    }      
Spring Tx (二) (事务案例及源码 1)
  • InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation: 实例化前
  • BeanPostProcessor.postProcessAfterInitialization: 初始化后

InfrastructureAdvisorAutoProxyCreator 是基础构建类

AbstractAutoProxyCreator.postProcessBeforeInstantiation()

@Override
  public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
        return null;
      }
      //是否基础构件(基础构建不需要代理):Advice、Pointcut、Advisor、AopInfrastructureBean这四类都算基础构建
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
        //添加进advisedBeans ConcurrentHashMap<k=Object,v=Boolean>标记是否需要增强实现,这里基础构建bean不需要代理,都置为false,供后面postProcessAfterInitialization实例化后使用。
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return null;
      }
    }

     // TargetSource是spring aop预留给我们用户自定义实例化的接口,如果存在TargetSource就不会默认实例化,而是按照用户自定义的方式实例化,咱们没有定义,不进入
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
        this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
    }

    return null;
  }      

AbstractAutoProxyCreator.postProcessAfterInitialization():

@Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {       // 如果是用户自定义获取实例,不需要增强处理,直接返回
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }// 查询map缓存,标记过false,不需要增强直接返回
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }// 判断一遍springAOP基础构建类,标记过false,不需要增强直接返回
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // 获取增强List<Advisor> advisors
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);       // 如果存在增强
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);// 标记增强为TRUE,表示需要增强实现          // 生成增强代理类
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
     // 如果不存在增强,标记false,作为缓存,再次进入提高效率,第16行利用缓存先校验
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }      

createProxy():

protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
     // 如果是ConfigurableListableBeanFactory接口(咱们DefaultListableBeanFactory就是该接口的实现类)则,暴露目标类
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {          //给beanFactory->beanDefinition定义一个属性:k=AutoProxyUtils.originalTargetClass,v=需要被代理的bean class
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
     //如果不是代理目标类
        if (!proxyFactory.isProxyTargetClass()) {//如果beanFactory定义了代理目标类(CGLIB)
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);//代理工厂设置代理目标类
            }
            else {//否则设置代理接口(JDK)
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
     //把拦截器包装成增强(通知)
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);//设置进代理工厂
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);//空方法,留给子类拓展用,典型的spring的风格,喜欢处处留后路
     //用于控制代理工厂是否还允许再次添加通知,默认为false(表示不允许)
        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {//默认false,上面已经前置过滤了匹配的增强Advisor
            proxyFactory.setPreFiltered(true);
        }
        //代理工厂获取代理对象的核心方法
        return proxyFactory.getProxy(getProxyClassLoader());
    }      

最后生成的是Cglib代理类。

2.2.2 ProxyTransactionManagementConfiguration
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    //定义事务增强器
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor j = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(transactionAttributeSource());
        advisor.setAdvice(transactionInterceptor());
        advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        return advisor;
    }

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    //定义基于注解的事务属性资源
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    //定义事务拦截器
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(transactionAttributeSource());
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }
        return interceptor;
    }

}      

核心就是事务拦截器TransactionInterceptor

Spring Tx (二) (事务案例及源码 1)
Spring Tx (二) (事务案例及源码 1)

事务拦截器的拦截功能就是依靠实现了MethodInterceptor接口

@Override
    public Object invoke(final MethodInvocation invocation) throws Throwable {
        // Work out the target class: may be {@code null}.
        // The TransactionAttributeSource should be passed the target class
        // as well as the method, which may be from an interface.
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

        // 调用TransactionAspectSupport的 invokeWithinTransaction方法
        return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
            @Override
            public Object proceedWithInvocation() throws Throwable {
                return invocation.proceed();
            }
        });
    }      

invoke方法中调用了父类​

​TransactionAspectSupport​

​​的​

​invokeWithinTransaction()​

​方法

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
            throws Throwable {

        // 如果transaction attribute为空,该方法就是非事务(非编程式事务)
        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
        final PlatformTransactionManager tm = determineTransactionManager(txAttr);
        final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
     // 标准声明式事务:如果事务属性为空 或者 非回调偏向的事务管理器
        if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
            // Standard transaction demarcation with getTransaction and commit/rollback calls.
            TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
            Object retVal = null;
            try {
                // 这里就是一个环绕增强,在这个proceed前后可以自己定义增强实现
                // 方法执行
                retVal = invocation.proceedWithInvocation();
            }
            catch (Throwable ex) {
                // 根据事务定义的,该异常需要回滚就回滚,否则提交事务
                completeTransactionAfterThrowing(txInfo, ex);
                throw ex;
            }
            finally {//清空当前事务信息,重置为老的
                cleanupTransactionInfo(txInfo);
            }//返回结果之前提交事务
            commitTransactionAfterReturning(txInfo);
            return retVal;
        }
     // 编程式事务:(回调偏向)
        else {
            final ThrowableHolder throwableHolder = new ThrowableHolder();

            // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
            try {
                Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
                        new TransactionCallback<Object>() {
                            @Override
                            public Object doInTransaction(TransactionStatus status) {
                                TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                                try {
                                    return invocation.proceedWithInvocation();
                                }
                                catch (Throwable ex) {// 如果该异常需要回滚
                                    if (txAttr.rollbackOn(ex)) {
                                        // 如果是运行时异常返回
                                        if (ex instanceof RuntimeException) {
                                            throw (RuntimeException) ex;
                                        }// 如果是其它异常都抛ThrowableHolderException
                                        else {
                                            throw new ThrowableHolderException(ex);
                                        }
                                    }// 如果不需要回滚
                                    else {
                                        // 定义异常,最终就直接提交事务了
                                        throwableHolder.throwable = ex;
                                        return null;
                                    }
                                }
                                finally {//清空当前事务信息,重置为老的
                                    cleanupTransactionInfo(txInfo);
                                }
                            }
                        });

                // 上抛异常
                if (throwableHolder.throwable != null) {
                    throw throwableHolder.throwable;
                }
                return result;
            }
            catch (ThrowableHolderException ex) {
                throw ex.getCause();
            }
            catch (TransactionSystemException ex2) {
                if (throwableHolder.throwable != null) {
                    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                    ex2.initApplicationException(throwableHolder.throwable);
                }
                throw ex2;
            }
            catch (Throwable ex2) {
                if (throwableHolder.throwable != null) {
                    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                }
                throw ex2;
            }
        }
    }      
  1. createTransactionIfNecessary(): 如果必要的话创建事务
  2. InvocationCallback的proceedWithInvocation(): InvocationCallback是父类的内部回调接口,子类中实现该接口供父类调用,子类TransactionInterceptor中invocation.proceed()。回调方法执行
  3. completeTransactionAfterThrowing(): 异常回调
Spring Tx (二) (事务案例及源码 1)

createTransactionIfNecessary

protected TransactionInfo createTransactionIfNecessary(
            PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {

        // 如果还没有定义名字,把连接点的ID定义成事务的名称
        if (txAttr != null && txAttr.getName() == null) {
            txAttr = new DelegatingTransactionAttribute(txAttr) {
                @Override
                public String getName() {
                    return joinpointIdentification;
                }
            };
        }

        TransactionStatus status = null;
        if (txAttr != null) {
            if (tm != null) {
                status = tm.getTransaction(txAttr);
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
                            "] because no transaction manager has been configured");
                }
            }
        }
        return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
    }      
  1. getTransaction(): 根据事务属性获取事务TransactionStatus
  2. prepareTransactionInfo(): 构建一个TransactionInfo事务信息对象, 绑定当前线程 ThreadLocal

invocation.proceed(): 调用的是ReflectiveMethodInvocation.invoke()