@EnableTransactionManagement

@Import({TransactionManagementConfigurationSelector.class}组件导入了两个组件

  1. AutoProxyRegistrar
  2. ProxyTransactionManagementConfiguration

在ProxyTransactionManagementConfiguration里面主要创建了

  1. BeanFactoryTransactionAttributeSourceAdvisor
  2. AnnotationTransactionAttributeSource
  3. TransactionInterceptor

Spring 事务源码学习

 

 

TransactionInterceptor类图

事务拦截器,实现MethodInterceptor

 Spring 事务源码学习

 

事务增强器BeanFactoryTransactionAttributeSourceAdvisor类图

 Spring 事务源码学习

 

Spring 是如何管理事务的?

Spring事务管理主要包括3个接口,Spring的事务主要是由它们(PlatformTransactionManager,TransactionDefinition,TransactionStatus)三个共同完成的。

1. PlatformTransactionManager:事务管理器--主要用于平台相关事务的管理

主要有三个方法:

  • commit 事务提交;

  • rollback 事务回滚;

  • getTransaction 获取事务状态。

2. TransactionDefinition:事务定义信息--用来定义事务相关的属性,给事务管理器PlatformTransactionManager使用

这个接口有下面四个主要方法:

  • getIsolationLevel:获取隔离级别;

  • getPropagationBehavior:获取传播行为;

  • getTimeout:获取超时时间;

  • isReadOnly:是否只读(保存、更新、删除时属性变为false--可读写,查询时为true--只读)

事务管理器能够根据这个返回值进行优化,这些事务的配置信息,都可以通过配置文件进行配置。

3. TransactionStatus:事务具体运行状态--事务管理过程中,每个时间点事务的状态信息。

例如它的几个方法:

  • hasSavepoint():返回这个事务内部是否包含一个保存点,

  • isCompleted():返回该事务是否已完成,也就是说,是否已经提交或回滚

  • isNewTransaction():判断当前事务是否是一个新事务

声明式事务的优缺点

  • 优点:不需要在业务逻辑代码中编写事务相关代码,只需要在配置文件配置或使用注解(@Transaction),这种方式没有侵入性。

  • 缺点:声明式事务的最细粒度作用于方法上,如果像代码块也有事务需求,只能变通下,将代码块变为方法。

 

事务实现原理

1.创建代理对象

 代理对象生成入口图

Spring 事务源码学习

 

    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                //生成AOP代理对象 事务和AOP 都会生成代理对象
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        //不需要增强的
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        //是否是基础bean,是否需要跳过
        //shouldSkip 事务 跳过,AOP根据条件判断是否要跳过
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
        //如果有通知就创建代理对象 添加@aspect 或者实现Advice接口的 就是有通知
        //getAdvicesAndAdvisorsForBean 事务增强器对象
         //事务找到:BeanFactoryTransactionAttributeSourceAdvisor
        //得到Advisors 通知类 这里是区分aop和事务的 事务找到
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        //找到合适的通知器不为空
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
        //创建代理类
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
AbstractAutoProxyCreator后置处理器创建代理对象入口

相关文章: