Spring 从源码看事务——TransactionInterceptor事务拦截器&AOP

Spring 事务

Spring管理事务的方式

  • 编程式事务
  • 声明式事务(通过XML/注解配置)

Spring声明式事务的内部实现方式

image.png

image.png

可以看到PlatformTransactionManager这个接口主要定义了3个方法
getTransaction获取事务,commit提交,rollback回滚

image.png
AbstractPlatformTransactionManager抽象类实现了Spring事务的标准流程,其子类DataSourceTransactionManager是我们使用较多的JDBC单数据源事务管理器,而JtaTransactionManager是JTA(Java Transaction API)规范的实现类,另外两个则分别是JavaEE容器WebLogic和WebSphere的JTA事务管理器的具体实现。

TransactionInterceptor#invoke()拦截入口

image.png
当执行decreaseStock()时我们首先关注
org.springframework.transaction.interceptor#TransactionInterceptor//可以认为下的invoke方法,这里是拦截入口,在这里可以看到真正执行事务配置的还是TransactionInterceptor父类TransactionAspectSupport的invokeWithinTransaction方法,参数1表示被调用的方法,在这里就是我们被@Transactional修饰的createOrder方法;参数2表明是哪一个target class调用了该方法,在这里是service.impl.OrderServiceImpl

TransactionAspectSupport类

// 通过BeanFactoryAware获取到BeanFactory
// InitializingBean的afterPropertiesSet是对Bean做一些验证(经常会借助它这么来校验Bean~~~)
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {

	// 注意此方法是个静态方法  并且是protected的  说明只有子类能够调用,外部并不可以~~~
	@Nullable
	protected static TransactionInfo currentTransactionInfo() throws NoTransactionException {
		return transactionInfoHolder.get();
	}
	
	// 外部调用此Static方法,可获取到当前事务的状态
	public static TransactionStatus currentTransactionStatus() throws NoTransactionException {
		TransactionInfo info = currentTransactionInfo();
		if (info == null || info.transactionStatus == null) {
			throw new NoTransactionException("No transaction aspect-managed TransactionStatus in scope");
		}
		return info.transactionStatus;
	}

        ···

	// 接下来就只剩我们最为核心的处理事务的模版方法了:
	//protected修饰,不允许其他包和无关类调用
	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {

		// 获取事务属性源(所有方法都在)
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 获取当前方法的事务属性
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);

		// 确定由哪一个事务管理器管理当前事务。
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
                 
        /*响应式编程的事务支持 我们这里
        不深入探讨(加入学习计划,指响应式编程~*/
		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
		     ···
		}
		
		// 转换为标准的PlatformTransactionManager
		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);

		// 拿到目标方法唯一标识(类.方法,如service.impl.OrderServiceImpl#createOrder)
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		// 如果txAttr为空 或者tm不属于CallbackPreferringPlatformTransactionManager(需要通过回调函数实现事务),执行目标增强
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
		
        // 创建事务对象,其中保存了事务状态对象(无论是否真的有创建)
        // TransactionInfo是一个事务对象,对象中包含事务的所有属性,包括PlatformTransactionManager、TransactionAttribute、TransactionStatus
        // ⚠️事务的管理都是通过TransactionInfo对象来完成,它封装了事务对象和事务处理的状态信息
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			
			Object retVal = null;
			try {
				//回调方法执行,执行目标方法(原有的业务逻辑)
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// 出现异常了,进行回滚(注意:并不是所有异常都会rollback的)

				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				//清除信息
				cleanupTransactionInfo(txInfo);
			}
	
			// 目标方法完全执行完成后,提交事务~~~
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		//编程式事务处理(CallbackPreferringPlatformTransactionManager) 会走这里
		//原理类似 这里跳过
		else {
		···
	}

	// 确定当前事务的事务管理器
	@Nullable
	protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
		// 如果这两个都没配置,所以肯定是手动设置了PlatformTransactionManager的,那就直接返回即可
		if (txAttr == null || this.beanFactory == null) {
			return getTransactionManager();
		}

		// qualifier 指定特定的事务管理器
		String qualifier = txAttr.getQualifier();
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(this.beanFactory, qualifier);
		}
		// 若没有指定qualifier   那再看看是否指定了 transactionManagerBeanName
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
		}
		// 若都没指定,那就不管了。直接根据类型去容器里找 getBean(Class)
		else {
			TransactionManager defaultTransactionManager = getTransactionManager();
			if (defaultTransactionManager == null) {
				defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
				if (defaultTransactionManager == null) {
		// 此处:若容器内有两个PlatformTransactionManager ,那就铁定会报错啦~~~
					defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
		// 如果事务管理器默认缓存(存储默认事务管理器的专用key值DEFAULT_TRANSACTION_MANAGER_KEY)中为空就加入缓存			this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			return defaultTransactionManager;
		}
	}
}


image.png
image.png