spring transactional手动提交事务_Spring 事务提交回滚源码解析

TransactionInterceptor

它是用来执行事务功能的,它是一个方法拦截器,如下所示:

df17d04268d2f1af076f5f5a66be5946.png

它实现了 MethodInterceptor 接口,而该接口只有一个 invoke 方法,用来执行目标方法

public Object invoke(MethodInvocation invocation) throws Throwable {
	Class<?> targetClass = (invocation.getThis() != null ?AopUtils.getTargetClass(invocation.getThis()) : null);
    // 调用父类的方法
	return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}

父类的 invokeWithinTransaction 方法定义了一个事务方法执行的框架,而每一步再细分为方法进行实现,代码如下:

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation){
	// 1. 获取事务属性
	TransactionAttributeSource tas = getTransactionAttributeSource();
	final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
	// 2. 获取事务管理器
	final PlatformTransactionManager tm = determineTransactionManager(txAttr);
	// 3. 获取需要事务的方法名称:类目.方法名
	final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
	// 4. 声明式事务
	if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
		// 5. 获取该方法上事务的信息
		TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
		Object retVal = null;
		try {
			// 6. 目标方法执行,它是一个拦截器链
			retVal = invocation.proceedWithInvocation();
		}
		catch (Throwable ex) {
			// 7. 事务回滚
			completeTransactionAfterThrowing(txInfo, ex);
			throw ex;
		}
		finally {
			// 8. 清除事务信息
			cleanupTransactionInfo(txInfo);
		}
		// 9. 事务提交
		commitTransactionAfterReturning(txInfo);
		return retVal;
	}
	else {
		// 10. 编程式事务,流程和声明式事务一致
	}
}

一个事务方法执行流程大概有以下几个步骤:

1. 获取事务属性
2. 获取事务管理器
3. 获取需要事务的方法名称
5. 获取该方法上事务的信息
6. 目标方法执行
7. 事务回滚
8. 清除事务信息
9. 事务提交

获取事务属性

首先去获取方法上面 Translational 注解的属性,在 Spring 事务初始化源码分析 中已经分析过了,即在 AnnotationTransactionAttributeSource.computeTransactionAttribute 中进行获取。

获取事务管理器

每个事务都由对应的事务管理器,所以在事务开始钱需要获取对应的事务管理器

protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
	if (txAttr == null || this.beanFactory == null) {
		return getTransactionManager();
	}
	// 事务管理器名称
	String qualifier = txAttr.getQualifier();
	if (StringUtils.hasText(qualifier)) {
		return determineQualifiedTransactionManager(this.beanFactory, qualifier);
	}
	else if (StringUtils.hasText(this.transactionManagerBeanName)) {
		return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
	}
	else {
		// 默认事务管理器
		PlatformTransactionManager defaultTransactionManager = getTransactionManager();
		defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
		// .....
		return defaultTransactionManager;
	}
}

获取需要事务的方法名称

这里主要去获取名称的名称,为 全限定类名+方法名的方式:method.getDeclaringClass().getName() + '.' + method.getName();

获取方法上事务的信息

该部分是 Spring 事务最复杂的部分,比如说去创建一个事务,设置事务的隔离级别,超时时间,对事务传播方式的处理,事务的挂起和恢复等;事务信息 TransactionInfo 包含了目标方法执行前的所有状态信息,如果方法执行失败,则会根据该信息来进行回滚。

对应方法为:

TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

代码如下所示:

创建事务

protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm,
		TransactionAttribute txAttr, final String joinpointIdentification) {
	// 设置事务的名称,为方法全限定名joinpointIdentification
	if (txAttr != null && txAttr.getName() == null) {
		txAttr = new DelegatingTransactionAttribute(txAttr) {
			public String getName() {
				return joinpointIdentification;
			}
		};
	}
	TransactionStatus status = null;
	if (txAttr != null) {
		if (tm != null) {
		    // 获取事务
			status = tm.getTransaction(txAttr);
		}
	}
	// 创建事务信息
	return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

获取事务

在方法 getTransaction 中获取事务,是最为复杂的逻辑,在其中处理隔离级别,超时时间和传播方式等。

public final TransactionStatus getTransaction(TransactionDefinition definition){
	// 获取事务
	Object transaction = doGetTransaction();
    // ...
	// 如果已经存在事务了,则处理事务的传播方式,如挂起存在的事务,新建事务等
	if (isExistingTransaction(transaction)) {
		return handleExistingTransaction(definition, transaction, debugEnabled);
	}
	// .....
	
	// 如果不存在事务,且事务的传播方式为 mandatory, 则抛出异常
	if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
		throw new IllegalTransactionStateException("....");
	}
	else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
			definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
			definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
		SuspendedResourcesH
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值