一、开启事务
1.@EnableTransactionManagement
通过@EnableTransactionManagement注解开启事务,@Import注解可以为容器中导入组件TransactionManagementConfigurationSelector
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement { }
2.TransactionManagementConfigurationSelector
在IOC容器中加载bean定义的时候会回调selectImports方法,返回值是需要导入类的全类名路径数组,然后这个类就会被加载到容器中,其中PROXY分支(默认)会导入AutoProxyRegistrar、ProxyTransactionManagementConfiguration两个类。
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
//AdviceMode mode() default AdviceMode.PROXY;默认是PROXY
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
...
}
2.1AutoProxyRegistrar
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
...
if (mode == AdviceMode.PROXY) {
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
...
*2.1.1InfrastructureAdvisorAutoProxyCreator
AopConfigUtils,最终注册InfrastructureAdvisorAutoProxyCreator到容器中
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
InfrastructureAdvisorAutoProxyCreator继承关系,实现了BeanPostProcessor后置处理器,用于处理事务。
注:如果同时启用AOP和事务,那么AOP的后置处理器AnnotationAwareAspectJAutoProxyCreator会覆盖事务的后置处理器InfrastructureAdvisorAutoProxyCreator,因为两者的BeanDefinition是同样的名字AUTO_PROXY_CREATOR_BEAN_NAME,根据内部维护的优先级,AnnotationAwareAspectJAutoProxyCreator优先级大于InfrastructureAdvisorAutoProxyCreator(2>0),这样就会由AnnotationAwareAspectJAutoProxyCreator来处理事务。
//AopConfigUtils内部维护优先级
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
static {
// Set up the escalation list...
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
*2.2ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration事务相关配置类,其中配置两个Bean:TransactionAttributeSource、TransactionInterceptor。
与AOP不同:AOP是根据@Before、@After等Advise解析成Advisor;事务通过ProxyTransactionManagementConfiguration配置类直接注册一个内置的BeanFactoryTransactionAttributeSourceAdvisor。因为AOP的增强代码是由我们自己编写配置的,而事务的增强代码是由Spring内置实现的。
Advisor包含Advise和Pointcut:其中Advise就是TransactionInterceptor,增强代码用于处理事务;Pointcut切点是TransactionAttributeSourcePointcut,用于匹配Bean是否符合创建动态代理条件(Bean或者Bean方法有@transactional注解),通过AnnotationTransactionAttributeSource对象解析@Transactional注解,一旦解析到就说明有资格创建动态代理。
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
//导入internalTransactionAdvisor,包含pointcut和advise
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());//用于解析注解@Transactional
advisor.setAdvice(transactionInterceptor());//内置Advice
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
/**
* 事务属性源对象:用于获取事务属性对象
* @return
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}
/**
* 用户拦截事务方法执行的
* @return
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {...}
}
二、解析advisor
与AOP处理流程类似,拿到BeanFactoryTransactionAttributeSourceAdvisor放入到缓存中。
BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
public List<Advisor> findAdvisorBeans() {
...
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
...
//ioc容器中找到了我们配置的BeanFactoryTransactionAttributeSourceAdvisor
for (String name : advisorNames) {
//判断是不是一个合适的bean
if (isEligibleBean(name)) {
...
else {
try {
//显示的调用getBean方法方法创建我们的BeanFactoryTransactionAttributeSourceAdvisor返回
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
...
三、创建动态代理
与AOP处理流程类似,拿到缓存中的BeanFactoryTransactionAttributeSourceAdvisor;匹配Pointcut时类级别的筛选会永远返回True,方法级别的筛选:本方法是否有@Transactional—>接口方法是否有@Transactional—>父类方法是否有@Transactional—>本类是否有@Transactional—>接口是否有@Transactional—>父类是否有@Transactional。
1.matches
TransactionAttributeSourcePointcut#matches
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches(Method method, @Nullable Class<?> targetClass) {
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
/**
* 获取TransactionAttributeSource对象
*/
TransactionAttributeSource tas = getTransactionAttributeSource();
// 通过getTransactionAttribute看是否有@Transactional注解
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
...
2.getTransactionAttribute
AbstractFallbackTransactionAttributeSource#getTransactionAttribute
@Override
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
...
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
...
}
3.computeTransactionAttribute
AbstractFallbackTransactionAttributeSource#computeTransactionAttribute
@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
//判断我们的事务方法上的修饰符是不是public的
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 拿到具体实现方法
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
//第一步,解析具体方法
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
//第二步:解析方法所在实现类
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
。。。
@Nullable
protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);
4.findTransactionAttribute
AnnotationTransactionAttributeSource#findTransactionAttribute实现
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
@Nullable
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
//获取注解解析器,3种,一般使用Spring的
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
//通过注解解析器去解析方法上的注解
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
![image-20211117135504477](https://dew-95255.oss-cn-beijing.aliyuncs.com/dew_blog/image-20211117135504477.png)
5.parseTransactionAnnotation
SpringTransactionAnnotationParser#parseTransactionAnnotation
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
@Override
@Nullable
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
//从element对象中获取@Transactional注解 然后把注解属性封装到了AnnotationAttributes
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
//解析出真正的事务属性对象
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
6.createProxy
匹配成功之后就会创建动态代理,流程与AOP类似。
四、调用方法
1.invoke
责任链调用方式与AOP类似,最终会调用到TransactionInterceptor#invoke方法
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
*2.invokeWithinTransaction
TransactionAspectSupport#invokeWithinTransaction,处理事务相关逻辑,包括开启、回滚、提交等。
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
...
//处理声明式事务
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
//开启事务
//根据事务传播行为,判断是否有必要
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
try {
//调用钩子函数回调目标方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
//回滚事务
//抛出异常时调用
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//清空线程变量中transactionInfo的值
cleanupTransactionInfo(txInfo);
}
//提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 编程式事务
...
}
*3.createTransactionIfNecessary
TransactionAspectSupport#createTransactionIfNecessary,根据事务传播行为判断是否开启事务,以及处理嵌套事务等逻辑。
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
...
//获取一个事务状态
status = tm.getTransaction(txAttr);
...
//把事物状态和事物属性等信息封装成一个TransactionInfo对象
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
4.getTransaction
AbstractPlatformTransactionManager#getTransaction
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
//获取事务对象
Object transaction = doGetTransaction();
...
//判断是不是已经存在了事务(嵌套事务)
//通过ConnectionHolder判断,如果为null,说明是外层事务;如果不为null,说明已经开启了事务。
if (isExistingTransaction(transaction)) {
//处理存在的事务
//嵌套事务就不会走下面逻辑
return handleExistingTransaction(definition, transaction, debugEnabled);
}
...
//判断事务传播行为,默认PROPAGATION_REQUIRED
//PROPAGATION_MANDATORY:表示必须运行在事务中,若当前没有事务就抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
...
}
//以下三个都会开启一个事务
//PROPAGATION_REQUIRED:当前存在事务就加入到当前的事务,没有就新开一个
//PROPAGATION_REQUIRES_NEW:新开一个事务,若当前存在事务就挂起当前事务
//PROPAGATION_NESTED:表示如果当前正有一个事务在运行中,则该方法应该运行在一个嵌套的事务中,被嵌套的事务可以独立于封装事务进行提交或者回滚(保存点),如果封装事务不存在,行为就像PROPAGATION_REQUIRES_NEW
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//挂起当前事务
//因为经过了isExistingTransaction(transaction)判断当前是不存在事务的,所以传递null表示不挂起事务
SuspendedResourcesHolder suspendedResources = suspend(null);
...
try {
...
//开启一个新的事务
doBegin(transaction, definition);
//把当前的事务属性绑定到线程变量去(事务隔离级别、事务激活、是否只读、事务名称)
prepareSynchronization(status, definition);
return status;
...
doGetTransaction,获取事务对象
@Override
protected Object doGetTransaction() {
...
//TransactionSynchronizationManager事务同步管理器对象,该类中都是局部线程变量,用来保存当前事务的信息。
//第一次从这里去线程变量中获取ConnectionHolder(数据库连接持有者),以数据源obtainDataSource为key,会返回null,因为还没有存放。
//ConnectionHolder为null,说明是外层事务;如果不为null,说明已经开启了事务。
//第二次进来(嵌套事务)会获取到ConnectionHolder
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
//返回事务对象
return txObject;
}
doBegin,开启事务
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
...
//获取配置的数据源的连接
Connection newCon = obtainDataSource().getConnection();
...
//把数据库连接包装成一个ConnectionHolder对象,然后设置到txObject对象中
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
...
//开启事务
con.setAutoCommit(false);
...
}
handleExistingTransaction,处理嵌套事务
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException {
//NEVER 存在外部事务:抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {...}
//NOT_SUPPORTED 存在外部事务:挂起外部事务,不创建新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {...}
//REQUIRES_NEW 存在外部事务:挂起外部事务,创建新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {...}
//NESTED 存在外部事务:融合到外部事务中
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {...}
...
}
suspend,挂起事务
@Nullable
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
...
if (transaction != null) {
//挂起事务,移除ConnectionHolder,设置为null
//移除后其他线程就无法获取外层事务,实现挂起
suspendedResources = doSuspend(transaction);
}
//获取外层事务(已存在事务)名称并清空线程变量
...
//获取外层事务(已存在事务)是否是只读事务并清空线程变量
...
//获取外层事务(已存在事务)的隔离级别并清空线程变量
...
//获取外层事务(已存在事务)是否激活并清空线程变量
...
//把从线程变量中获取出来的外层事务(已存在事务)属性封装为SuspendedResourcesHolder返回
//TransactionSynchronizationManager-->SuspendedResourcesHolder
return new SuspendedResourcesHolder(
suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
...
}