《Spring源码深度解析 郝佳 第2版》事务

往期博客


《Spring源码深度解析 郝佳 第2版》容器的基本实现与XML文件的加载

《Spring源码深度解析 郝佳 第2版》XML标签的解析

《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决

《Spring源码深度解析 郝佳 第2版》ApplicationContext

《Spring源码深度解析 郝佳 第2版》AOP

《Spring源码深度解析 郝佳 第2版》JDBC、MyBatis原理


目录

<tx:annoation-driven >自定义标签开启事务管理

  • TxNamespaceHandler的init方法注册AnnotationDriverBeanDefinitionParser
  • AnnotationDriverBeanDefinitionParser的parse方法
    • 注册InfrastructureAdvisorAutoProxyCreator
    • 注册三个事务相关的bean
  • AOP织入实现逻辑
    • findAdvisorsThatCanApply方法
    • 核心逻辑canApply解析找出增强链advisors,并解析封装@Transaction配置信息到TransactionAttribute
    • 根据advisors创建动态创建代理对象
  • 代理对象执行事务逻辑TransactionInterceptor
    • invokeWithinTransaction事务初始化
    • 声明式事务-创建事务
    • 声明式事务-事务回滚
    • 声明式事务-事务提交

一、<tx:annoation-driven >自定义标签

Spring声明式事务让我们从复杂的事务处理中得到解脱,使我们不在关注获取连接,关闭连接,事务提交回滚等操作,不用再try…catch…finally处理逻辑,解耦代码。

  • 在Spring中使用声明式事务的方式就是在xml配置文件加上<tx:annoation-driven transcation-manager="transactionManager">,然后在方法上面加上@Transaction即可
  • 在SpringBoot中使用声明式事务控制就是引入如jdbc的starter依赖之后不需要任何额外配置就可以用@Transactional注解进行事务的使用。因为SpringBoot的自动装配,根据依赖会自动进行加上@EnableTransactionManager,然后自动分别注入DataSourceTransactionManager或JpaTransactionManager

注意:

  • 默认情况下Spring中的事务处理只对RuntimeExeceptoin异常回滚,对Exception不会回滚。
  • @Transactional注解可以应用于类和方法。声明类时,该注解默认作用于类和子类的所有方法,应用于public方法才有效;
  • 父类方法要加入同等级别的注解,需要单独声明。isolation和timeout两个属性仅对新启动的事务有效,专为Propagation.REQUIRED和Propagation.REQUIRES_NEW使用而设计。
    在这里插入图片描述

<tx:annoation-driven transcation-manager="transactionManager" mode="proxy">标签是Spring中声明事务开启的开关。Spring中的事务的管理是依赖SpringAOP的的,可以指定mode属性为aspectj或者是proxy,也就是指定是编译时织入和运行时织入

proxy:利用动态代理在运行时对目标编织进切面代码。则其他属性可以控制代理的行为。
此时处于代理模式,只有代理调用的方法可以被拦截,在同一类中的本地调用无法被拦截。此时类内方法级别的调用不会走代理,因为事务是有代理对象开启的,所以对实例的内部调用方法不会开启事务。即使方法声明了@Transactional注解。

aspectj:会在编译时或加载时向切面影响目标(方法/类)位置编织进切面代码;
此时与代理无关,所以自调用也可以被编入切面。此时proxyTargetClass属性将会被忽略,并且spring-aspects模块的jar文件需要配置在classpath
无论调用是否涉及代理、无论调用方法是否声明了@Transactional注解,调用都会被拦截,包括本地调用。

————————————————
版权声明:本文为CSDN博主「weixin_40562288」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40562288/article/details/93159006

1. TxNamespaceHandler的init方法

首先注册AnnotationDriverBeanDefinitionParser。之前分析aop、bean的xml文件解析的时候知道,只要是自定义标签,一定有对应的XxxNamespaceHandler处理器,然后在init方法中会注册XxxBeanDefinitionParser解析器调用parse方法内部,根据mode来选择是 aspectj还是proxy,是proxy的话注册XxxAutoProxyCreator的BeanDefinition

// TxNamespaceHandler.init()
public void init() {
        this.registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
        this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        this.registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
    }

2. AnnotationDriverBeanDefinitionParser的parse方法

parse 方法根据mode选择静态、动态代理,默认是proxy动态代理,然后调用configureAutoProxyCreator方法

  1. 注册InfrastructureAdvisorAutoProxyCreator: 根据xml中配置了事务开启的标签创建 ,它间接继承AbstractAutoProxyCreator,间接实现SmartInstantiationAwareBeanPostProcessor来调用postProcessAfterInitalization方法对所有bean完成AOP织入逻辑
  2. 注册AnnotationTransactionAttributeSource:它实现接口TransactionAttributeSource内部方法有isCandidateClass、getTransactionAttribute等方法,然后重写findTransactionAttribute等系列方法解析封装@Transaction注解配置信息到TransactionAttribute中
  3. 注册TransactionInterceptor:包含TransactionManager和TransactionAttributeSource,支持事务的创建、提交、回滚等
  4. 注册BeanFactoryTransactionAttributeSourceAdvisor: 事务AOP的抽象

在这里插入图片描述

// AnnotationDriverBeanDefinitionParser.parse()
@Nullable
    public BeanDefinition parse(Element element, ParserContext parserContext) {
    	// 1. 注册时间监听器
        this.registerTransactionalEventListenerFactory(parserContext);
        String mode = element.getAttribute("mode");
        // aspectj模式
        if ("aspectj".equals(mode)) {
            this.registerTransactionAspect(element, parserContext);
            if (ClassUtils.isPresent("javax.transaction.Transactional", this.getClass().getClassLoader())) {
                this.registerJtaTransactionAspect(element, parserContext);
            }
        } else {
        	// proxy模式,对应注解模式
        	// 2. AopAutoProxyConfigurer 是静态内部类,主要是创建注册器
            AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
        }

        return null;
    }
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
			
			// 2.1. 注册 InfrastructureAdvisorAutoProxyCreator 的BeanDefinition
            AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
            
            String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
            
            if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
                Object eleSource = parserContext.extractSource(element);
                
                // 2.2. 创建 AnnotationTransactionAttributeSource 类型的BeanDefinition,可以感知@Transaction注解
                RootBeanDefinition sourceDef = new  RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
                
                sourceDef.setSource(eleSource);
                sourceDef.setRole(2);
                String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
				
				// 2.3. 创建TransactionInterceptor类型的BeanDefinition
                RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
                
                interceptorDef.setSource(eleSource);
                interceptorDef.setRole(2);
                AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
                interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
                
                // 2.4. BeanFactoryTransactionAttributeSourceAdvisor,这个就是需要的增强
                RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
                
                advisorDef.setSource(eleSource);
                advisorDef.setRole(2);
                advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
                
                if (element.hasAttribute("order")) {
                    advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
                }
				// 注册
                parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
                CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
                compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
                parserContext.registerComponent(compositeDef);
            }

        }
    }
// 2.1. 注册InfrastructureAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator间接继承AbstractAutoProxyCreator,间接实现SmartInstantiationAwareBeanPostProcessor来调用postProcessAfterInitalization方法完成AOP逻辑

// AopNamespaceUtils
public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
		// 注册 InfrastructureAdvisorAutoProxyCreator 
        BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
       // 对proxy-target-class、expose-proxy属性的处理
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        
        registerComponentIfNecessary(beanDefinition, parserContext);
    }

InfrastructureAdvisorAutoProxyCreator 的继承体系
在这里插入图片描述

// 2.2 注册其他3个事务核心实现的BeanDefinition

其中三个核心的bean支撑起事务的全部功能
在这里插入图片描述

1. BeanFactoryTransactionAttributeSourceAdvisor

可以理解为所需事务功能的抽象,它的成员属性

  • TransactionAttributeSource:内部方法可以获取TransactionAttribute配置信息,可以理解在@Transaction注解配置的信息
  • TransactionAttributeSourcePointcut:为什么需要再引入TransactionAttributeSourcePointcut?其实有点类似装饰者模式,在不继承的情况下增强成员属性的功能,其实他就是封装的TransactionAttributeSource,因为canApply涉及当前bean的匹配,为了更方便,因此在TransactionAttributeSourcePointcut增加了一个matches方法将接口、类内所有方法的Pointcut以及Advice,也就是advisor

它的方法

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
    // 成员属性
    @Nullable
    private TransactionAttributeSource transactionAttributeSource;
    
    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            return BeanFactoryTransactionAttributeSourceAdvisor.this.transactionAttributeSource;
        }
    };

    public BeanFactoryTransactionAttributeSourceAdvisor() {
    }
	// 设置 transactionAttributeSource
    public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
        this.transactionAttributeSource = transactionAttributeSource;
    }
	// 设置 TransactionInterceptor拦截器
    public void setClassFilter(ClassFilter classFilter) {
        this.pointcut.setClassFilter(classFilter);
    }

    public Pointcut getPointcut() {
        return this.pointcut;
    }
}
2. TransactionAttributeSource ,可以理解为事务资源抽象

主要作用是判断是否是待增强事务资源,然后提供获得@Transaction注解信息,然后封装保存注解配置信息到TransactionAttribute

public interface TransactionAttributeSource {

	// 是否需要事务增强
	default boolean isCandidateClass(Class<?> targetClass) {
		return true;
	}

	// 获取封装@Transaction注解的信息
	@Nullable
	TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass);

3. TransactionInterceptor ,可以理解为拦截事务方法进行环绕增强入事务创建、提交、回滚等

主要作用是处理声明式事务、编程式事务的逻辑,使用TransactionManager进行提交、回滚的逻辑

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

	// 构造函数
	public TransactionInterceptor() {
	}
	// 有三种情况 TransactionManager 可以设置

	// 1. TransactionManager 
	public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {
		setTransactionManager(ptm);
		setTransactionAttributeSource(tas);
	}
	
	// 2. PlatformTransactionManager 
	@Deprecated
	public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
		setTransactionManager(ptm);
		setTransactionAttributeSource(tas);
	}
	
	// 3. PlatformTransactionManager 
	@Deprecated
	public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
		setTransactionManager(ptm);
		setTransactionAttributes(attributes);
	}


	
	// 事务方法执行
	@Override
	@Nullable
	public Object invoke(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);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		// 真正的执行代理对象增强方法以及事务方法
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}


	// 序列化方法省略

	

}
3. AOP织入实现逻辑
  1. 在bean的postProcessAfterInitialization时机,注册的InfrastructureAdvisorAutoProxyCreator 的方法会调用AbstractAutoProxyCreator的wrapIfNecessary方法进行根据条件判断是否该bean需要封装,也就是该bean是否需要被增强
  2. wrapIfNecessary调用getAdvicesAndAdvisorsForBean方法逻辑,寻找当前bean能用到的advices和advisors,保存到 specificInterceptors 链中
    • 找出指定bean对应的增强器findCandidateAdvisors,内部逻辑就是使用BeanFactoryUtils的getBeanNameForType方法获取全部增强的BeanDefinition
    • findAdvisorsThatCanApply遍历全部的增强器将适用当前bean的保存到增强拦截器链中,内部逻辑就是调用canApply逻辑(重要),
      • 找出BeanFactoryTransactionAttributeSourceAdvisor类型的advisor
      • 找出TransactionAttributeSource然后解析封装@Transaction配置的信息
  3. 根据ProxyFactory封装advisors并创建代理
// AbstractAutoProxyCreator

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            	// 1. 调用wrapIfNessary方法
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }





// 3.1 wrapIfNecessary
// AbstractAutoProxyCreator
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
        
        	// 2. getAdvicesAndAdvisorsForBean,寻找当前bean能用到的advices、advisors,封装到 specificInterceptors 链中
        	// 其中advisor = advice + pointcut
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                
                // 3. 创建代理对象,可以选用JDK或者是Cglib
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
// getAdvicesAndAdvisorsForBean
// 2.1 getAdvicesAndAdvisorsForBean
 @Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
        return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
    }

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    	// 2.1.1 findCandidateAdvisors
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        // 2.1.2 findAdvisorsThatCanApply
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }
// findAdvisorsThatCanApply找到适用的增强器

返回增强拦截器链

// AbstractAutoProxyCreator
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
        ProxyCreationContext.setCurrentProxiedBeanName(beanName);

        List var4;
        try {
        	// 调用 AopUtils.findAdvisorsThatCanApply 找出当前bean能用的增强链
            var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        } finally {
            ProxyCreationContext.setCurrentProxiedBeanName((String)null);
        }

        return var4;
    }
// 委托AopUtils
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        } else {
        	// 作为返回结果
            List<Advisor> eligibleAdvisors = new ArrayList();
            Iterator var3 = candidateAdvisors.iterator();
            // 先处理引介增强,也就是引介增强需要放到前面
            // IntroductionAdvisor与PointcutAdvisor最本质上的区别就是,IntroductionAdvisor只能应用于类级别的拦截,
            // 只能使用Introduction型的Advice。
            while(var3.hasNext()) {
                Advisor candidate = (Advisor)var3.next();
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            Iterator var7 = candidateAdvisors.iterator();
			// 处理普通bean的增强
            while(var7.hasNext()) {
                Advisor candidate = (Advisor)var7.next();
                // 关键就是这个canApply方法
                if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            return eligibleAdvisors;
        }
    }
// canApply逻辑分析

接着上面canApply分析,对于遍历到的advisor判断能否对当前bean应用,如果是存在事务advisor,那么就要查找当前bean中的方法是否配置了@Transaction注解,然后解析@Transaction中的配置到TransactionAttribute

  1. 首先判断当前遍历到的增强器advisor是否为PonitcouAdvisor,也就是是否存在事务advisor即BeanFactoryTransactionAttributeSourceAdvisor,因为之前已经注册了,然后进入canApply方法
  2. canApply方法内部判断当前bean中是否存在加了@Transaction注解的事务方法
    1. 调用的BeanFactoryTransactionAttributeSourceAdvisor的getPointcut方法获取 TransactionAttributeSourcePointcut
    2. 接着再次调用canApply方法传入pointcut,该重载方法的逻辑就是首先获取该bean所对应的类的全部接口连同类本身保存在set集合,然后遍历,遍历过程又对类中所有方法Methods遍历,使用TransactionAttributeSourcePointcutmatches方法,内部拿到TransactionAttributeSource然后调用getTransactionAttribute方法,实际调用的是AbstractFallbackTransactionAttributeSource的方法开始进行@Transaction注解配置信息解析到TransactionAttribute

// AopUtils

 public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        if (advisor instanceof IntroductionAdvisor) {
            return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
        } 
        // 关键 PointcutAdvisor ,这里和事务增强器完成结合的地方
        // 事务实现的BeanFactoryTransactionAttributeSourceAdvisor继承PointcutAdvisor
        
        else if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pca = (PointcutAdvisor)advisor;
            // BeanFactoryTransactionAttributeSourceAdvisor.getPointcut()返回的就是 TransactionAttributeSourcePointcut
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        } else {
            return true;
        }
    }
// AopUtils
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
		// 此时的pc是 TransactionAttributeSourcePointcut
		
        // 是否配置了过滤某些增强bean
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        } else {
        	// 获得自己TransactionAttributeSourcePointcut,下面需要调用他的matches方法
            MethodMatcher methodMatcher = pc.getMethodMatcher();

            if (methodMatcher == MethodMatcher.TRUE) {
                return true;
            } else {
            	// 引介增强
                IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
                if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                    introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
                }
				// 所有的父类、父接口、本类
                Set<Class<?>> classes = new LinkedHashSet();
                if (!Proxy.isProxyClass(targetClass)) {
                    classes.add(ClassUtils.getUserClass(targetClass));
                }

                classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
                Iterator var6 = classes.iterator();
				// 遍历全部类,取出方法
                while(var6.hasNext()) {
                    Class<?> clazz = (Class)var6.next();
                    // 获取全部方法
                    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                    Method[] var9 = methods;
                    int var10 = methods.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        Method method = var9[var11];
                        if (introductionAwareMethodMatcher != null) {
                            if (introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) {
                                return true;
                            }
                        } 
                        // 方法匹配增强器,
                        // 此方法就是调用TransactionAttributeSourcePointcut
                        else if (methodMatcher.matches(method, targetClass)) {
                            return true;
                        }
                    }
                }

                return false;
            }
        }
    }
// TransactionAttributeSourcePointcut
@Override
	public boolean matches(Method method, Class<?> targetClass) {
		// 事务标签资源
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 获取事务标签
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}

因此在此进行AbstractFallbackTransactionAttributeSource的getTransactionAttribute方法调用,委托computeTransactionAttribute解析@Transaction注解配置的信息到TransactionAttribute

// AbstractFallbackTransactionAttributeSource
@Override
	@Nullable
	public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// First, see if we have a cached value.
		Object cacheKey = getCacheKey(method, targetClass);
		TransactionAttribute cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			// Value will either be canonical value indicating there is no transaction attribute,
			// or an actual transaction attribute.
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
				return cached;
			}
		}
		else {
			// We need to work it out.
			// 解析@Transaction注解配置信息,委托给computeTransactionAttribute方法
			
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			// Put it in the cache.
			if (txAttr == null) {
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
				String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
				if (txAttr instanceof DefaultTransactionAttribute) {
					((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}

// computeTransactionAttribute封装事务标签@Transaction配置信息TransactionAttribute

对于事务注解@Transaction可以加载类、方法上面,也可以加在父接口以及方法上面,具体逻辑就是找到并封装

// 1. 然后就到了AnnotationTransactionAttributeSource中的findTransactionAttribute

// 2. 然后来到了SpringTransactionAnnotationParser的parseTransactionAnnotation,封装@Transaction注解信息 parseTransactionAnnotation到TransactionAttribute

@Nullable
	protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// Don't allow no-public methods as required.
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		// The method may be on an interface, but we need attributes from the target class.
		// If the target class is null, the method will be unchanged.
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

		// First try is the method in the target class.
		// 查看该方法是否有事务声明
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// Second try is the transaction attribute on the target class.
		
		// 查看方法所在类是否存在事务声明
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}
		// 存在接口,就去接口中找
		if (specificMethod != method) {
			// Fallback is to look at the original method.
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
			// Last fallback is the class of the original method.
			// 到接口的类中寻找
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}

// 1. 然后就到了AnnotationTransactionAttributeSource中的findTransactionAttribute

@Override
	@Nullable
	protected TransactionAttribute findTransactionAttribute(Method method) {
		return determineTransactionAttribute(method);
	}
//调用
@Nullable
	protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		for (TransactionAnnotationParser parser : this.annotationParsers) {
			TransactionAttribute attr = parser.parseTransactionAnnotation(element);
			if (attr != null) {
				return attr;
			}
		}
		return null;
	}

// 2. 然后来到了SpringTransactionAnnotationParser的parseTransactionAnnotation,封装@Transaction注解信息 parseTransactionAnnotation到TransactionAttribute

@Override
	@Nullable
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}
//
// SpringTransactionAnnotationParser
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());
		rbta.setTimeout(attributes.getNumber("timeout").intValue());
		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));

		List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		rbta.setRollbackRules(rollbackRules);

		return rbta;
	}

// 3.2 createProxy创建代理对象

根据获取到的advisos和其他信息封装到ProxyFactory中,然后创建代理对象返回,创建代理对象的方式可以采用JDK或者是Cglib动态代理

// AbstractAutoProxyCreator
 protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
		//统一将适用的specificInterceptors链封装为advisors
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        // 将advisors保存到proxyFactory
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        // 传统初始化
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
		// 返回代理对象
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }


// 3.2.1具体的实现在父类ProxyCreatorSupport中
// ProxyCreatorSupport

// 构造函数初始化 DefaultAopProxyFactory
public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

// 创建
protected final synchronized AopProxy createAopProxy() {

		// 主要是初始化监听器
        if (!this.active) {
            this.activate();
        }
		// 
        return this.getAopProxyFactory().createAopProxy(this);
    }
// 3.2.2在DefaultAopProxyFactory中判断选用JDK还是Cglib
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    public DefaultAopProxyFactory() {
    }
	
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    	// JDK
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            }
            // Cglib 
            else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
    }
}

4. TransactionInterceptor

前面分析了对bean进行AOP织入的逻辑,从所有增强器中找到该bean能用的事务advisor,其实也是注册的BeanFactoryTransactionAttributeSourceAdvisor,然后解析封装了@Transaction注解中配置的信息到TransactionAttribute中,然后将事务advisor放到了ProxyFactory中然后创建了代理对象。

The most important concepts to grasp with regard to the Spring Framework’s declarative transaction support are that this support is enabled via AOP proxies and that the transactional advice is driven by metadata (currently XML- or annotation-based).The combination of AOP with transactional metadata yields an AOP proxy that uses a TransactionInterceptor in conjunction with an appropriate TransactionManager implementation to drive transactions around method invocations.

关于Spring框架的声明式事务支持,要掌握的最重要的概念是,这种支持是通过AOP代理启用的,并且事务建议是由元数据驱动的(目前是基于XML或注释的)。AOP 与事务元数据的组合将生成一个 AOP 代理,该代理使用TransactionInterceptor和适当的TransactionManager实现来驱动围绕方法调用的事务。

接下来分析代理对象的事务方法执行逻辑,关键就是事务功能实现的三个类最后一个TransactionInterceptor,它实现MethodInterceptor,执行了代理对象的事务方法都会被拦截,然后就是通过环绕增强进行事务的创建、提交、回滚等

在这里插入图片描述

声明式事务的实现就是通过环绕增强的方式,在目标方法执行之前开启事务,在目标方法执行之后提交或者回滚事务

  • 前置增强(org.springframework.aop.BeforeAdvice):在目标方法执行之前进行增强;
  • 后置增强(org.springframework.aop.AfterReturningAdvice):在目标方法执行之后进行增强;
  • 环绕增强(org.aopalliance.intercept.MethodInterceptor):在目标方法执行前后都执行增强;
  • 异常抛出增强(org.springframework.aop.ThrowsAdvice):在目标方法抛出异常后执行增强;
  • 引介增强(org.springframework.aop.IntroductionInterceptor):为目标类添加新的方法和属性。

在这里插入图片描述

// 事务处理逻辑invokeWithinTransaction

主要是进行事务准备工作

  1. 获取当前事务资源TransactionAttributeSource
  2. 获取事务注解配置信息TransactionAttribute
  3. 获取事务抽象管理器TransactionManager
  4. 反应式事务处理逻辑
  5. 平台事务处理逻辑
    • 声明式事务管理
    • 编程式事务管理

先看TransactionInterceptor的invoke方法,委托了TransactionAspectSupport的invokeWithinTransaction方法。

// TransactionInterceptor
@Override
	@Nullable
	public Object invoke(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);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		
		// 委托TransactionAspectSupport类完成
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}

// 委托TransactionAspectSupport类完成
@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		
		// 1. 如果没有@Transaction表示不是事务方法
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 2. 获取事务标签配置信息
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		// 3. 获取 TransactionManager 
		final TransactionManager tm = determineTransactionManager(txAttr);
		
		// 4.1 反应式事务处理,ReactiveTransactionManager
		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			...
			...
			});
			
		}
		
		// 4.2 平台事务处理,PlatformTransactionManager 
		
		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		// 一、声明式事务
		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			...
			...
		}

		// 二、编程式事务
		else {
			...
			...
		}
	}
5. 事务功能抽象接口分析
5.1 TransactionManager抽象事务管理器

The key to the Spring transaction abstraction is the notion of a transaction strategy.A transaction strategy is defined by a TransactionManager

Spring事务抽象的关键是事务策略的概念。事务策略由 TransactionManager 定义。
在这里插入图片描述

public interface PlatformTransactionManager extends TransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}
5.2TransactionDefinition抽象事务标准概念
  • 传播:通常,事务范围内的所有代码都在该事务中运行。但是,如果事务方法在事务上下文已存在时运行,则可以指定该行为。例如,代码可以继续在现有事务中运行(常见情况),也可以挂起现有事务并创建新事务。Spring 提供了 EJB CMT 所熟悉的所有事务传播选项。要了解 Spring 中事务传播的语义,请参阅事务传播.Propagation: Typically, all code within a transaction scope runs in that transaction. However, you can specify the behavior if a transactional method is run when a transaction context already exists. For example, code can continue running in the existing transaction (the common case), or the existing transaction can be suspended and a new transaction created. Spring offers all of the transaction propagation options familiar from EJB CMT. To read about the semantics of transaction propagation in Spring, see Transaction Propagation.

  • 隔离:此事务与其他事务的工作隔离的程度。例如,此事务能否看到来自其他事务的未提交写入。Isolation: The degree to which this transaction is isolated from the work of other transactions. For example, can this transaction see uncommitted writes from other transactions?

  • 超时:此事务在超时并由底层事务基础结构自动回滚之前运行的时间。Timeout: How long this transaction runs before timing out and being automatically rolled back by the underlying transaction infrastructure.

  • 只读状态:当代码读取但不修改数据时,可以使用只读事务。在某些情况下,只读事务可能是一种有用的优化,例如当您使用Hibernate时。Read-only status: You can use a read-only transaction when your code reads but does not modify data. Read-only transactions can be a useful optimization in some cases, such as when you use Hibernate.

5.3TransactionStatus抽象事务代码控制状态

The TransactionStatus interface provides a simple way for transactional code to control transaction execution and query transaction status. The concepts should be familiar, as they are common to all transaction APIs.

TransactionStatus 接口为事务代码控制事务执行和查询事务状态提供了一种简单的方法。

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {

    @Override
    boolean isNewTransaction();

    boolean hasSavepoint();

    @Override
    void setRollbackOnly();

    @Override
    boolean isRollbackOnly();

    void flush();

    @Override
    boolean isCompleted();
}
6.声明式事务分析

我们可以看到createTransactionIfNecessary、commitTransactionAfterReturning和completeTransactionAfterThrowing都是针对该接口编程,并不依赖于特定事务管理器,这里是对Spring事务抽象的实现。

  1. createTransactionIfNecessary在目标方法执行前创建事务TransactionInfo,它内部包含TransactionAttributeSourceTransactionManagerTransactionStatus属性等,这几个属性在前面都有介绍
  2. 执行目标方法
  3. 出现异常尝试回滚处理completeTransactionAfterThrowing
  4. 提交事务前的事务信息清除
  5. 提交事务commitTransactionAfterReturning
// TransactionAspectSupport 的声明式事务处理

if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			
			// (1) 创建事务返回TransactionInfo 
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				
				// (2)执行事务方法
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				// (3) 事务回滚信息
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				// (4)清除事务信息
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}
			// (4) 提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
(1) 获取事务createTransactionIfNecessary返回TransactionInfo

需要先知道创建事务返回TransactionInfo ,它是事务的抽象,主要包含的成员变量有
在这里插入图片描述
在这里插入图片描述


// TransactionInfo
@Nullable
		
		// 1. 事务管理器
		private final PlatformTransactionManager transactionManager;
		
		// 2. 事务标签封装信息
		// 其中 TransactionAttribute  继承 TransactionDefinition
		@Nullable
		private final TransactionAttribute transactionAttribute;

		private final String joinpointIdentification;
		
		// 3. 事务状态
		@Nullable
		private TransactionStatus transactionStatus;

		// 4. 旧的备份
		@Nullable
		private TransactionInfo oldTransactionInfo;

createTransactionIfNecessary创建事务

// TransactionAspectSupport

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

		// If no name specified, apply method identification as transaction name.
		
		// 1. 重新封装 DelegatingTransactionAttribute
		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) {
				// 2. 获取事务状态,DelegatingTransactionAttribute继承TransactionDefinition
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
		// 3. 封装TransactionInfo
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}
//1. 重新封装 DelegatingTransactionAttribute
//2. 获取或创建事务getTransaction整体流程

主要作用是

  • // 2.1 默认缺省事务定义
  • // 2.2 委托doGetTransaction
  • // 2.3 判断当前线程是否存在事务,判断依据为当前线程记录的连接不为空,而且connectHolder中的transactionActive属性不为空当前线程已经存在事务,转向嵌套事务的处理
  • // 2.4 事务超时验证
  • // 2.5 当前线程不存在事务,但是传播行为是PROPAGATION_MANDATORY,则抛出异常
  • // 2.6 当前线程已存在事务,需要根据传播行为处理,传播行为是PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED,但是还需要创建新的事务,则空挂起
  • // 2.7 开启事务,进行数据库的连接,内部调用doBegin设置事务的同步信息与数据库的连接

// AbstractPlatformTransactionManager
@Override
	public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException {

		// Use defaults if no transaction definition given.
		// 2.1 默认缺省事务定义
		
		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

		// 2.2 委托doGetTransaction
		Object transaction = doGetTransaction();

		boolean debugEnabled = logger.isDebugEnabled();
		
		// 2.3 判断当前线程是否存在事务,判断依据为当前线程记录的连接不为空,而且connectHolder中的transactionActive属性不为空
		
		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			// 当前线程已经存在事务处理逻辑
			return handleExistingTransaction(def, transaction, debugEnabled);
		}

		// Check definition settings for new transaction.
		// 2.4 事务超时验证
		if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
		}

		// No existing transaction found -> check propagation behavior to find out how to proceed.
		// 2.5 当前不存在事务,但是传播行为为PROPAGATION_MANDATORY,则抛出异常
		if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
		// 2.6 当前存在事务,但是还需要创建新的事务,空挂起
		else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
			}
			try {
				// 2.7 开启事务,进行数据库的连接
				return startTransaction(def, transaction, debugEnabled, suspendedResources);
			}
			catch (RuntimeException | Error ex) {
				resume(null, suspendedResources);
				throw ex;
			}
		}
		else {
			// Create "empty" transaction: no actual transaction, but potentially synchronization.
			if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
				logger.warn("Custom isolation level specified but no actual transaction initiated; " +
						"isolation level will effectively be ignored: " + def);
			}
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
		}
	}
// 2.2 委托doGetTransaction获取当前线程事务
// AbstractPlatformTransactionManager
protected Object doGetTransaction() {
		// 当前事务对象
        DataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject();
        // 设置保存点
        txObject.setSavepointAllowed(this.isNestedTransactionAllowed());
		// 如果当前线程已经记录数据库连接使用原连接
        ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.obtainDataSource());
        // false表示非新创建连接
        txObject.setConnectionHolder(conHolder, false);
        return txObject;
    }
// 2.2.1 TransactionSynchronizationManager保证事务隔离性

可以看到,获取当前事务对象时,使用了TransactionSynchronizationManager#getResource方法,类图如下:

在这里插入图片描述
TransactionSynchronizationManager通过ThreadLocal对象在当前线程记录了resources和synchronizations属性。

  • resources是一个HashMap,用于记录当前参与事务的事务资源,方便进行事务同步,在DataSourceTransactionManager的例子中就是以dataSource作为key,保存了数据库连接,这样在同一个线程中,不同的方法调用就可以通过dataSource获取相同的数据库连接,从而保证所有操作在一个事务中进行。
  • synchronizations属性是一个TransactionSynchronization对象的集合,AbstractPlatformTransactionManager类中定义了事务操作各个阶段的调用流程,有很多trigger前缀的方法,这些方法用于在事务操作的各个阶段触发回调,从而可以精确控制在事务执行的不同阶段所要执行的操作,这些回调实际上都通过TransactionSynchronizationUtils来实现,它会遍历TransactionSynchronizationManager#synchronizations集合中的TransactionSynchronization对象,然后分别触发集合中各个元素对应方法的调用
// TransactionSynchronizationManager 

public abstract class TransactionSynchronizationManager {

	private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class);

	// 保存一个线程事务的隔离性
	private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<>("Transactional resources");

	// 事务处理阶段的各种回调
	private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
			new NamedThreadLocal<>("Transaction synchronizations");

	private static final ThreadLocal<String> currentTransactionName =
			new NamedThreadLocal<>("Current transaction name");

	private static final ThreadLocal<Boolean> currentTransactionReadOnly =
			new NamedThreadLocal<>("Current transaction read-only status");

	private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
			new NamedThreadLocal<>("Current transaction isolation level");

	private static final ThreadLocal<Boolean> actualTransactionActive =
			new NamedThreadLocal<>("Actual transaction active");

}

// TransactionSynchronizationUtils 的 TransactionSynchronization对象回调,如在提交前执行

public static void triggerBeforeCommit(boolean readOnly) {
		for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
			synchronization.beforeCommit(readOnly);
		}
	}
// 2.3 当前线程已经存在事务

事务的7种传播行为参考:https://zhuanlan.zhihu.com/p/52143061

  1. // PROPAGATION_REQUIRES_NEW:如果当前存在事务,把当前事务使用suspend挂起,新建事务。挂起的的原因是方便原事务还原。
  2. // PROPAGATION_NESTED:如果当前存在事务,并且子事务是嵌套事务,他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,而nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。

提到事务传播机制时,我们经常提到一个条件“如果当前已有事务”,那么Spring是如何知道当前是否已经开启了事务呢?

// 在AbstractPlatformTransactionManager中是这样做的:
protected boolean isExistingTransaction(Object transaction) throws TransactionException {
		return false;
	}

// DataSourceTransactionManager
// 判断依据为当前线程记录的连接不为空,而且connectHolder中的transactionActive属性不为空,
// 即当前线程已存在事务,则会影响下面的传播行为,
protected boolean isExistingTransaction(Object transaction) {
        DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
        return txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive();
    }

然后就是根据设置的传播行为进行处理

// AbstractPlatformTransactionManager
private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {

		// 1. PROPAGATION_NEVER:不支持事务,非事务的形式运行
		
		// 直接抛出异常
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}
		
		// 2. PROPAGATION_NOT_SUPPORTED:支持当前事务,如果当前没有事务,就以非事务方式执行。
		
		// 挂起当前事务
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction");
			}
			// 挂起当前事务
			Object suspendedResources = suspend(transaction);
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}
		// 3. PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

		// 挂起当前事务
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction, creating new transaction with name [" +
						definition.getName() + "]");
			}
			// 挂起当前事务
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			try {
				// 再新建一个事务
				return startTransaction(definition, transaction, debugEnabled, suspendedResources);
			}
			catch (RuntimeException | Error beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
		}
		// 4. PROPAGATION_NESTED:嵌套事务,他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,
		// 而nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			if (!isNestedTransactionAllowed()) {
				throw new NestedTransactionNotSupportedException(
						"Transaction manager does not allow nested transactions by default - " +
						"specify 'nestedTransactionAllowed' property with value 'true'");
			}
			if (debugEnabled) {
				logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
			}
			// 嵌套子事务使用保存点
			if (useSavepointForNestedTransaction()) {
				// Create savepoint within existing Spring-managed transaction,
				// through the SavepointManager API implemented by TransactionStatus.
				// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
						// 设置回滚保存点
				status.createAndHoldSavepoint();
				return status;
			}
			// 直接开启事务
			else {
				// Nested transaction through nested begin and commit/rollback calls.
				// Usually only for JTA: Spring synchronization might get activated here
				// in case of a pre-existing JTA transaction.
				return startTransaction(definition, transaction, debugEnabled, null);
			}
		}

		// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
		if (debugEnabled) {
			logger.debug("Participating in existing transaction");
		}
		
		// 隔离级别
		if (isValidateExistingTransaction()) {
			if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
				Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
					Constants isoConstants = DefaultTransactionDefinition.constants;
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] specifies isolation level which is incompatible with existing transaction: " +
							(currentIsolationLevel != null ?
									isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
									"(unknown)"));
				}
			}
			if (!definition.isReadOnly()) {
				if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] is not marked as read-only but existing transaction is");
				}
			}
		}
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}
// 2.7 获取或创建事务,进行数据库的连接startTransaction

构造Transaction,包括设置ConnectionHolder、隔离级别、timeout、如果是新连接绑定到当前线程

// AbstractPlatformTransactionManager
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
			boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		// 事务状态
		DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
		// 连接数据库,开启连接
		doBegin(transaction, definition);
		// 准备同步器
		prepareSynchronization(status, definition);
		return status;
	}



// 2.7.1真正的开启事务doBegin

可以说事务是从这个doBegin方法开始的,主要是对DataSourceTransactionManager.DataSourceTransactionObject属性填充

  1. 尝试获取连接,并不是每次都获取新连接,如果当前线程connectionHolder已经存在,则没有必要再次获取,或者对于事务同步表示设置为true的需要重新获取连接
  2. 设置隔离级别以及只读标识,
  3. 更改默认的自动提交
  4. 设置标志位
  5. 设置过期时间
  6. 调用TransactionSynchronizationManager将connectionHolder绑定到当前线程
// DataSourceTransactionManager  实现 AbstractPlatformTransactionManager

protected void doBegin(Object transaction, TransactionDefinition definition) {
		// 2.8.1 DataSourceTransactionManager
		
        DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
        Connection con = null;

        try {
            if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
                Connection newCon = this.obtainDataSource().getConnection();
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
                }

                txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
            }

            txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
            con = txObject.getConnectionHolder().getConnection();
            
            // 2.8.2 设置隔离级别
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
            txObject.setPreviousIsolationLevel(previousIsolationLevel);
            txObject.setReadOnly(definition.isReadOnly());

			// 2.8.3 更改自动提交
            if (con.getAutoCommit()) {
                txObject.setMustRestoreAutoCommit(true);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
                }

                con.setAutoCommit(false);
            }
			
			// 2.8.4 底层数据库的连接,设置只读、隔离级别
            this.prepareTransactionalConnection(con, definition);
            
            // 2.8.5 判断线程是否存在事务的依据
            
            txObject.getConnectionHolder().setTransactionActive(true);
            int timeout = this.determineTimeout(definition);
            if (timeout != -1) {
                txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
            }

            if (txObject.isNewConnectionHolder()) {
            	// 将当前获得的连接绑定到当前线程
                TransactionSynchronizationManager.bindResource(this.obtainDataSource(), txObject.getConnectionHolder());
            }

        } catch (Throwable var7) {
            if (txObject.isNewConnectionHolder()) {
                DataSourceUtils.releaseConnection(con, this.obtainDataSource());
                txObject.setConnectionHolder((ConnectionHolder)null, false);
            }

            throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7);
        }
    }
// 2.7.2设置传播行为prepareConnectionForTransaction
 @Nullable
    public static Integer prepareConnectionForTransaction(Connection con, @Nullable TransactionDefinition definition) throws SQLException {
        Assert.notNull(con, "No Connection specified");
        boolean debugEnabled = logger.isDebugEnabled();
        if (definition != null && definition.isReadOnly()) {
            try {
                if (debugEnabled) {
                    logger.debug("Setting JDBC Connection [" + con + "] read-only");
                }

                con.setReadOnly(true);
            } catch (RuntimeException | SQLException var5) {
                for(Object exToCheck = var5; exToCheck != null; exToCheck = ((Throwable)exToCheck).getCause()) {
                    if (exToCheck.getClass().getSimpleName().contains("Timeout")) {
                        throw var5;
                    }
                }

                logger.debug("Could not set JDBC Connection read-only", var5);
            }
        }

        Integer previousIsolationLevel = null;
        if (definition != null && definition.getIsolationLevel() != -1) {
            if (debugEnabled) {
                logger.debug("Changing isolation level of JDBC Connection [" + con + "] to " + definition.getIsolationLevel());
            }

            int currentIsolation = con.getTransactionIsolation();
            if (currentIsolation != definition.getIsolationLevel()) {
                previousIsolationLevel = currentIsolation;
                con.setTransactionIsolation(definition.getIsolationLevel());
            }
        }

        return previousIsolationLevel;
    }

//3. 封装事务信息prepareTransactionInfo

当已经创建事务连接并且完成了事务信息的提取之后,我们需要将所有的事务信息统一记录到TransactionInfo中,包含目标方法前所有的状态信息,一旦事务执行失败,Spring会通过TransactionInfo信息来进行回滚等操作

// TransactionAspectSupport

protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, String joinpointIdentification,
			@Nullable TransactionStatus status) {
		// 封装实例创建
		TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
		
		// 事务方法
		if (txAttr != null) {
		
			// We need a transaction for this method...
			if (logger.isTraceEnabled()) {
				logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
			}
			// The transaction manager will flag an error if an incompatible tx already exists.
			txInfo.newTransactionStatus(status);
		}
		// 非事务方法
		else {
			// The TransactionInfo.hasTransaction() method will return false. We created it only
			// to preserve the integrity of the ThreadLocal stack maintained in this class.
			if (logger.isTraceEnabled()) {
				logger.trace("No need to create transaction for [" + joinpointIdentification +
						"]: This method is not transactional.");
			}
		}

		// We always bind the TransactionInfo to the thread, even if we didn't create
		// a new transaction here. This guarantees that the TransactionInfo stack
		// will be managed correctly even if no transaction was created by this aspect.
		
		// 事务信息绑定当前线程
		txInfo.bindToThread();
		return txInfo;
	}
(3) 声明式事务-事务回滚信息
  • 回滚条件:发生异常首先判断ex是不是RunntimeException或者是Error,是的话进行回滚逻辑,控制回滚的类主要是TransactionManager实现类AbstractPlatformTransactionManager
  • 回顾情况的考虑:同样也需要根据当前事务的状态判断,独立事务直接回滚,带有保存点的事务直接回退到保存点,若事务不是独立的事务 则标记状态,等到事务链执行完毕统一回滚
  • 回滚逻辑:在txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());实现
// TransactionAspectSupport

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
		// 发生异常先判断当前是否存在事务
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
			
			if (logger.isTraceEnabled()) {
				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
						"] after exception: " + ex);
			}
			// 发生异常ex,首先判断ex是不是RunntimeException或者是Error
			if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
				try {
					// 回滚
					txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
				}
				catch (TransactionSystemException ex2) {
					logger.error("Application exception overridden by rollback exception", ex);
					ex2.initApplicationException(ex);
					throw ex2;
				}
				catch (RuntimeException | Error ex2) {
					logger.error("Application exception overridden by rollback exception", ex);
					throw ex2;
				}
			}
			else {
				// We don't roll back on this exception.
				// Will still roll back if TransactionStatus.isRollbackOnly() is true.
				try {
					// 如果不满足回滚条件即使爆出异常也同样会提交
					txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
				}
				catch (TransactionSystemException ex2) {
					logger.error("Application exception overridden by commit exception", ex);
					ex2.initApplicationException(ex);
					throw ex2;
				}
				catch (RuntimeException | Error ex2) {
					logger.error("Application exception overridden by commit exception", ex);
					throw ex2;
				}
			}
		}
	}
// AbstractPlatformTransactionManager
@Override
	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, false);
	}
1. 回滚情况的考虑

需要考虑的当前的事务是不是独立事务,也可能涉及多个事务链的调用

  1. // 当前事务有保存点会回滚到保存点:也就是当前事务为单独的线程,回滚点信息在TransactionInfo中保存
  2. // 当前事务是新事务直接回滚:外部事务
  3. // 当前事务不是独立的事务设置完标记状态后则直接返回:需要外部事务执行完成统一控制回滚。

// AbstractPlatformTransactionManager
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
		try {
			boolean unexpectedRollback = unexpected;

			try {
				// 1. 激活所有TransactionSynchronization中对应的回调方法
				triggerBeforeCompletion(status);
				
				// 2.1 如果有保存点,也就是当前事务为单事务
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Rolling back transaction to savepoint");
					}
					// 如果有保存点,也就是当前事务为单独的线程则会退到保存点
					status.rollbackToHeldSavepoint();
				}
				// 2.2 当前事务是独立事务,且没有保存点
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction rollback");
					}
					// 独立事务直接回滚
					doRollback(status);
				}
				else {
					// 2.3 当前事务不是独立的事务,也就是当前事务是新开的事务,先不会滚,等到外部事务统一回滚
					// Participating in larger transaction
					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");
					}
					// Unexpected rollback only matters here if we're asked to fail early
					if (!isFailEarlyOnGlobalRollbackOnly()) {
						unexpectedRollback = false;
					}
				}
			}
			catch (RuntimeException | Error ex) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				throw ex;
			}

			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

			// Raise UnexpectedRollbackException if we had a global rollback-only marker
			if (unexpectedRollback) {
				throw new UnexpectedRollbackException(
						"Transaction rolled back because it has been marked as rollback-only");
			}
		}
		finally {
			// 清空记录的资源并将挂起的资源恢复
			cleanupAfterCompletion(status);
		}
	}
2. 回滚逻辑

// doRollback真正的回滚

// DataSourceTransactionManager
 protected void doRollback(DefaultTransactionStatus status) {
        DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        if (status.isDebug()) {
            this.logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
        }

        try {
            con.rollback();
        } catch (SQLException var5) {
            throw new TransactionSystemException("Could not roll back JDBC transaction", var5);
        }
    }
3. 清空记录的资源将挂起的资源恢复
// DataSourceTransactionManager
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		// 设置完成状态,避免重复调用,无论是否回滚成功都要调用
		status.setCompleted();
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.clear();
		}
		//  清除信息
		if (status.isNewTransaction()) {
			
			doCleanupAfterCompletion(status.getTransaction());
		}
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction after completion of inner transaction");
			}
			Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
			// 结束之前事务挂起的状态
			resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}

// 清空记录资源,也就是DataSourceTransactionManager的内部类

// DataSourceTransactionManager
 protected void doCleanupAfterCompletion(Object transaction) {
        DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
        // 将数据库的连接从当前事务解绑
        if (txObject.isNewConnectionHolder()) {
            TransactionSynchronizationManager.unbindResource(this.obtainDataSource());
        }
		// 释放连接
        Connection con = txObject.getConnectionHolder().getConnection();

        try {
            if (txObject.isMustRestoreAutoCommit()) {
            	// 设置自动提交
                con.setAutoCommit(true);
            }

            DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());
        } catch (Throwable var5) {
            this.logger.debug("Could not reset JDBC Connection after transaction", var5);
        }

        if (txObject.isNewConnectionHolder()) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
            }
			
			// 释放连接
            DataSourceUtils.releaseConnection(con, this.dataSource);
        }

        txObject.getConnectionHolder().clear();
    }

// 恢复挂起的事务,更新TransactionSynchronizationManager的同步信息,包含隔离级别、传播行为等

// DataSourceTransactionManager
protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
			throws TransactionException {

		if (resourcesHolder != null) {
			Object suspendedResources = resourcesHolder.suspendedResources;
			if (suspendedResources != null) {
				doResume(transaction, suspendedResources);
			}
			List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
			if (suspendedSynchronizations != null) {
				TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
				TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
				TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
				doResumeSynchronization(suspendedSynchronizations);
			}
		}
	}
(4)事务提交
1. 提交情况的考虑

原理同上述回滚逻辑,最后是委托DataSourceTransactionManager类拿到connection来进行提交

// TransactionAspectSupport
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
			}
			// 提交事务
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}
	}

不同的是在提交之前需要加一个判断,前面分析事务异常规则的时候,当某个事务既没有保存点又不是新事务,Spring对他的处理方式只是设置一个回滚标志。

这里就会用到这个标志,某个事务是另一个事务的嵌套事务,但是些事务又不在Spring的管辖范围,或者无法设置保存点,那么Spring就会根据回滚标志禁止事务的提交

当某个嵌入的事务发生回滚会设置回滚标志,一旦判断出当前事务流被设置了回滚标识,则有外部事务来统一的进行整体事务的回滚

// AbstractPlateformTransactionManager
@Override
	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, false);
			return;
		}

		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
			}
			processRollback(defStatus, true);
			return;
		}
		// 调用提交
		processCommit(defStatus);
	}
2.事务的提交

开始进入提交逻辑,在这里也是判断事务的提交逻辑,单事务直接提交,对于组合事务需要考虑保存点的情况和非单个事务的情况

  1. 当事务状态中有保存点信息的话,便不会去提交事务
  2. 当事务非新事务的时候也不会去提交事务

对于内嵌事务,在Spring中设置的是在内嵌事务开始之前设置保存点

  • 一旦内嵌事务发生异常需要回滚,就根据这个保存点保存的信息回滚
  • 如果内嵌事务没有出现异常,内嵌事务不会单独提交,而是根据事务流最外层事务负责提交,所以如果存在保存点就不是最外层事务,不做提交操作。
// AbstractPlatformTransactionManager
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
		try {
			boolean beforeCompletionInvoked = false;

			try {
				boolean unexpectedRollback = false;
				// 各种触发器,这些方法用于在事务操作的各个阶段触发回调,从而可以精确控制在事务执行的不同阶段所要执行的操作,
				// 这些回调实际上都通过TransactionSynchronizationUtils来实现,它会遍历TransactionSynchronizationManager#synchronizations集合中的
				// TransactionSynchronization对象,然后分别触发集合中各个元素对应方法的调用。
				
				prepareForCommit(status);
				triggerBeforeCommit(status);
				triggerBeforeCompletion(status);
				beforeCompletionInvoked = true;

				// 1. 当事务状态中有保存点信息的话便不会去提交事务
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Releasing transaction savepoint");
					}
					unexpectedRollback = status.isGlobalRollbackOnly();
					status.releaseHeldSavepoint();
				}
				// 2. 当前事务是新事务
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction commit");
					}
					unexpectedRollback = status.isGlobalRollbackOnly();
					doCommit(status);
				}
				//  3. 当事务非新事务的时候也不会去提交事务
				else if (isFailEarlyOnGlobalRollbackOnly()) {
					unexpectedRollback = status.isGlobalRollbackOnly();
				}

				// Throw UnexpectedRollbackException if we have a global rollback-only
				// marker but still didn't get a corresponding exception from commit.
				if (unexpectedRollback) {
					throw new UnexpectedRollbackException(
							"Transaction silently rolled back because it has been marked as rollback-only");
				}
			}
			catch (UnexpectedRollbackException ex) {
				// can only be caused by doCommit
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
				throw ex;
			}
			catch (TransactionException ex) {
				// can only be caused by doCommit
				if (isRollbackOnCommitFailure()) {
					doRollbackOnCommitException(status, ex);
				}
				else {
					triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				}
				throw ex;
			}
			catch (RuntimeException | Error ex) {
				if (!beforeCompletionInvoked) {
					triggerBeforeCompletion(status);
				}
				doRollbackOnCommitException(status, ex);
				throw ex;
			}

			// Trigger afterCommit callbacks, with an exception thrown there
			// propagated to callers but the transaction still considered as committed.
			try {
				triggerAfterCommit(status);
			}
			finally {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
			}

		}
		finally {
			// 清除记录事务信息
			cleanupAfterCompletion(status);
		}
	}

底层数据库连接的API

// DataSourceTransactionManager
 protected void doCommit(DefaultTransactionStatus status) {
        DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        if (status.isDebug()) {
            this.logger.debug("Committing JDBC transaction on Connection [" + con + "]");
        }

        try {
            con.commit();
        } catch (SQLException var5) {
            throw new TransactionSystemException("Could not commit JDBC transaction", var5);
        }
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scl、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值