码迷,mamicode.com
首页 > 编程语言 > 详细

spring tx——@EnableTransactionManagement

时间:2020-07-01 20:17:54      阅读:50      评论:0      收藏:0      [点我收藏+]

标签:ide   cti   intercept   ret   响应   tran   manage   完成   不同的   

@EnableTransactionManagement import了TransactionManagementConfigurationSelector,而TransactionManagementConfigurationSelector继承于AdviceModeImportSelector根据@EnableTransactionManagement配置的AdviceMode引入不同的类。

我们只看proxy模式下引入的AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

AutoProxyRegistrar——引入aop代理

AutoProxyRegistrar继承于ImportBeanDefinitionRegistrar,注册定义用于aop代理生成的InfrastructureAdvisorAutoProxyCreator的BeanDefinition

ProxyTransactionManagementConfiguration——生成事务相关类

  1. TransactionalEventListenerFactory:其父类AbstractTransactionManagementConfiguration生成一个TransactionalEventListenerFactory用于创建ApplicationListenerMethodTransactionalAdapter,向TransactionSynchronizationManager注册@TransactionalEventListener注解的方法生成的TransactionSynchronization。
  2. TransactionAttributeSource:用于解析事务注解,包括Spring的@Transactional、jta的@Transactional、ejb3的@TransactionAttribute注解
  3. TransactionInterceptor:事务通知Advice,完成事务的主要逻辑,底层将获取事务、回滚、提交委托给TransactionManager
  4. BeanFactoryTransactionAttributeSourceAdvisor:事务切面通知Advisor,通过TransactionAttributeSource判断方法是否包含事务注解,通过TransactionInterceptor完成事务通知。

TransactionInterceptor

TransactionInterceptor主要逻辑位于父类TransactionAspectSupport的invokeWithinTransaction方法

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {
		//1.通过TransactionAttributeSource解析事务注解获取TransactionAttribute,来决定使用何种TransactionManager
		TransactionAttributeSource tas = getTransactionAttributeSource();
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		final TransactionManager tm = determineTransactionManager(txAttr);

		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			//tm为ReactiveTransactionManager类型,即响应式的事务管理器逻辑,这里省略。。。
		}

		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
            //2.创建事务
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
			//3.执行后续通知和执行代码
			Object retVal;
			try {
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// 4.抛错异常判断是否回滚
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
                // 5.重置线程绑定的TransactionInfo
				cleanupTransactionInfo(txInfo);
			}

            //省略部分无关代码。。。。
            
            //6.提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			//tm为CallbackPreferringPlatformTransactionManager类型,即异步回调的事务管理器,使用execute处理事务,这里省略。。。
		}
	}

1. 根据事务注解决定TransactionManager

protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
		if (txAttr == null || this.beanFactory == null) {
			return getTransactionManager();
		}
		//获取注解配置的TransactionManager,例如@Transactional("dataSourceTransactionManager")
		String qualifier = txAttr.getQualifier();
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(this.beanFactory, qualifier);
		}
    	//获取TransactionInterceptor配置的默认transactionManagerBeanName
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
		}
		else {
            //获取TransactionInterceptor配置的默认transactionManager
			TransactionManager defaultTransactionManager = getTransactionManager();
			if (defaultTransactionManager == null) {
				defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
				if (defaultTransactionManager == null) {
                    //获取beanFactory中TransactionManager类型的bean
					defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
					this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			return defaultTransactionManager;
		}
	}

2. 创建事务

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

		//省略代码。。。
    
		//通过PlatformTransactionManager开启事务
		TransactionStatus status = null;
		if (txAttr != null) {
			if (tm != null) {
				status = tm.getTransaction(txAttr);
			}
		}
    	//封装TransactionInfo,并绑定到线程上(即存储在Threadlocal中)
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}

3. 执行后续通知和代码

4. 抛错异常判断是否回滚

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
            //1.事务注解上回滚的异常规则与当前异常匹配,执行回滚,即@Transactional(rollbackFor = Exception.class),ex instanceof Exception
			if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
				try {
					txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
				}
                //省略异常处理(日志和抛错)。。。。
				catch (TransactionSystemException ex2) {
				}
				catch (RuntimeException | Error ex2) {
				}
			}
            //1.事务注解上回滚的异常规则与当前异常不匹配,执行提交,但TransactionStatus.isRollbackOnly()为true也会进行回滚
			else {
				try {
					txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
				}
                //省略异常处理(日志和抛错)。。。。
				catch (TransactionSystemException ex2) {
				}
				catch (RuntimeException | Error ex2) {
				}
			}
		}
	}

5. 重置线程绑定的TransactionInfo

protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {
    	//重置为原来的TransactionInfo
		if (txInfo != null) {
			txInfo.restoreThreadLocalStatus();
		}
	}

6. 无异常提交事务

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 tx——@EnableTransactionManagement

标签:ide   cti   intercept   ret   响应   tran   manage   完成   不同的   

原文地址:https://www.cnblogs.com/wuweishuo/p/13221017.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!