首先事务是基于aop的,如果不了解aop的,建议先去看下我关于aop的文章: Spring之aop源码解析
先说结论,带着结论看源码。首先,在bean的生命周期中,
执行实例化前置增强,会加载所有切面并放入缓存,其中就包括我们事务增强的切面,在bean的初始化后置增强会遍历bean的所有方法是否有@Transactional,如果有则生成代理对象。当调用增强方法时,会先开启事务,然后在执行原方法,最后在提交事务或回滚。
事务使用

在SpringBoot中是默认开启了事务的,而在spring跟spring mvc中,开启事务需要手动的加上@EnableTransactionManagement注解。这是因为SpringBoot自动装配上TransactionAutoConfiguration类,这个类内部就有@EnableTransactionManagement注解。如果不了解自动装配,可以看下我这篇文章SpringBoot自动装配原理之深入源码解析
spring会解析@Import注解
而TransactionManagementConfigurationSelector实现了ImportSelector接口,spring会调用其selectImports方法

返回AutoProxyRegistrar,ProxyTransactionManagementConfiguration这两个类继续解析

AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,则会调用registerBeanDefinitions方法。



向容器中注入InfrastructureAdvisorAutoProxyCreator类,前提是没有开启aop,因为aop的AnnotationAwareAspectJAutoProxyCreator功能更加强大。(向ioc注入一个BeanpostProcessor,顾名思义这个类用来进行自动代理)
ProxyTransactionManagementConfiguration是一个配置Bean,向容器内注入了TransactionInterceptor,TransactionAttributeSource,BeanFactoryTransactionAttributeSourceAdvisor这三个Bean,相当于advice,pointcut,advisor。
在spring的生命周期中,bean的实例化前置增强环节,会从ioc中加载所有切面,就会找到BeanFactoryTransactionAttributeSourceAdvisor,并放入缓存。我这里直接来到AbstractAutoProxyCreator的postProcessBeforeInstantiation方法,它是AbstractAutoProxyCreator是InfrastructureAdvisorAutoProxyCreator跟AnnotationAwareAspectJAutoProxyCreator的父类,不管有没有开启aop,都会调用这个方法。
我们的BeanFactoryTransactionAttributeSourceAdvisor是一个Advisor,所以被加入了adviseBeans缓存中。

我们直接来到Student这个Bean生命周期中的初始化后置增强
我这里遍历到AnnotationAwareAspectJAutoProxyCreator(因为我开启了aop,没有使用aop则是InfrastructureAdvisorAutoProxyCreator)

判断是否需要代理

匹配自己的切面


在方法1中,拿到之前缓存的BeanFactoryTransactionAttributeSourceAdvisor
在方法2中,遍历studentService所有方法是否匹配BeanFactoryTransactionAttributeSourceAdvisor,匹配规则是有@Transactional注解











找到@Transactional注解并封装成TransactionAttribute

上面就是匹配切面的过程
匹配成功生成代理对象
当调用事务方法时,执行切面逻辑
来到TransactionInterceptor的invoke方法


createTransactionIfNecessary

获取事务,此时事务为空

开启新的事务

创建新的事务并开启


将连接的自动提交设置为false

将连接放到threadLocal中


completeTransactionAfterThrowing

判断异常类型是否@Transactional指定类型,若没指定,使用默认类型




调用连接池或jdbc的回滚方法

commitTransactionAfterReturning



调用jdbc或连接池的commit方法

提交后,释放连接,并将threadlocal的连接移除






