Spring 注解事物@Transactional开发和源码分析

Spring 注解 事物开发

一、声明式事务:

环境搭建: 1、导入相关依赖 数据源、数据库驱动、Spring-jdbc模块

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.13.RELEASE</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.44</version>
</dependency>

2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据

3、给方法上标注 @Transactional 表示当前方法是一个事务方法;

@Transactional
public void add() {
    deptDao.insert();
    int i=10/0;
}

4、 @EnableTransactionManagement 开启基于注解的事务管理功能; @EnableXXX 5、配置事务管理器来控制事务; @Bean public PlatformTransactionManager transactionManager()

代码:

package com.willow.tx;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
@ComponentScan("com.willow.tx")
public class TxConfig {


    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource ();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://192.168.7.108/willow");
        ds.setUsername("root");
        ds.setPassword("123456");
        return ds;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(){
        return  new JdbcTemplate(dataSource());
    }

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

}

二、事物原理部分

1)、@EnableTransactionManagement注解

@Import(TransactionManagementConfigurationSelector.class)

利用TransactionManagementConfigurationSelector给容器中会导入下面两个组件

  • AutoProxyRegistrar

  • ProxyTransactionManagementConfiguration

    public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
     @Override
     protected String[] selectImports(AdviceMode adviceMode) {
    //AdviceMode在 EnableTransactionManagement注解中 默认为AdviceMode mode() default AdviceMode.PROXY;
      switch (adviceMode) {
       case PROXY:
        return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
       case ASPECTJ:
        return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
       default:
        return null;
      }
     }
    
    }

2)、AutoProxyRegistrar:

给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件

1.  AutoProxyRegistrar.registerBeanDefinitions() -->
    
2.  AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);   -->
    
3.    public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
  return registerAutoProxyCreatorIfNecessary(registry, null);
 }

4.public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
  return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);  //注册了一个InfrastructureAdvisorAutoProxyCreator组件
}
 
  • InfrastructureAdvisorAutoProxyCreator:?原理和AOP部分的AnnotationAwareAspectJAutoProxyCreator一样,利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

3)、ProxyTransactionManagementConfiguration 做了什么?

3.1 、给容器中注册事务增强器;

3.1.1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

    //事物增强器
 @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
 @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
  BeanFactoryTransactionAttributeSourceAdvisor advisor = 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();
 }
   // 2)、事务拦截器:
   // TransactionInterceptor;保存了事务属性信息,事务管理器;他是一个 MethodInterceptor;
    @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;
 }
}

3.1.2)、事务拦截器:

MethodInterceptor在目标方法执行的时候;

执行拦截器链;

事务拦截器:

​ 1)、先获取事务相关的属性

​ 2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger最终会从容器中按照类型获取一个PlatformTransactionManager;

​ 3)、执行目标方法

如果异常,获取到事务管理器,利用事务管理回滚操作;

如果正常,利用事务管理器,提交事务

3.1.2.1 MethodInterceptor在目标方法执行的时候;

TransactionInterceptor.invoke() 方法

@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
   
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

   
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
      @Override
      public Object proceedWithInvocation() throws Throwable {
         return invocation.proceed();
      }
   });
}

3.1.2.2 TransactionAspectSupport.invokeWithinTransaction()方法

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

   // 1)、先获取事务相关的属性
   final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
   // 2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger
   final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    //获取要执行的事物方法
   final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

   if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      // 创建一个事物
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      Object retVal = null;
      try {
         //事物方法的执行
         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)) {
                           // A RuntimeException: will lead to a rollback.
                           if (ex instanceof RuntimeException) {
                              throw (RuntimeException) ex;
                           }
                           else {
                              throw new ThrowableHolderException(ex);
                           }
                        }
                        else {
                           // A normal return value: will lead to a commit.
                           throwableHolder.throwable = ex;
                           return null;
                        }
                     }
                     finally {
                        cleanupTransactionInfo(txInfo);
                     }
                  }
               });

         // Check result state: It might indicate a Throwable to rethrow.
         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;
      }
   }
}
3.1.2.2.1)、获取PlatformTransactionManager

如果事先没有添加指定任何transactionmanger最终会从容器中按照类型获取一个PlatformTransactionManager

protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
   // Do not attempt to lookup tx manager if no tx attributes are set
   if (txAttr == null || this.beanFactory == null) {
      return getTransactionManager();
   }
   //判断是否@Transactional(transactionManager = "")指定了transactionManager
   String qualifier = txAttr.getQualifier();
   if (StringUtils.hasText(qualifier)) {
      return determineQualifiedTransactionManager(qualifier);
   }
   else if (StringUtils.hasText(this.transactionManagerBeanName)) {
      return determineQualifiedTransactionManager(this.transactionManagerBeanName);
   }
   else {
      PlatformTransactionManager defaultTransactionManager = getTransactionManager();
      if (defaultTransactionManager == null) {
         defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
         if (defaultTransactionManager == null) {
            defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
             //在IOC容器中获取PlatformTransactionManager
            this.transactionManagerCache.putIfAbsent(
                  DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
         }
      }
      return defaultTransactionManager;
   }
}

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/yangliuhbhd/article/details/80779575
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞