spring源码事务三源码

本文详细介绍了SpringBoot中基于AOP的事务管理机制,包括@Transational注解的工作原理,如如何开启事务、事务的传播行为、隔离级别、超时和只读属性的处理,以及在遇到异常时如何决定回滚或提交事务。通过分析TransactionInterceptor和TransactionAspectSupport的源码,揭示了事务管理的内部流程,包括创建、提交和回滚事务的关键步骤。
摘要由CSDN通过智能技术生成

当前源码基于spring boot 2.1.6.RELEASE版本

一.@EnableTransactionManagement是基于springAop实现的

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

接下来我们看一下 org.springframework.transaction.annotation.TransactionManagementConfigurationSelector,主要向项目注册了两个bean,AutoProxyRegistrar.class和ProxyTransactionManagementConfiguration.class


public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {determineTransactionAspectClass()};
			default:
				return null;
		}
	}

	private String determineTransactionAspectClass() {
		return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}

org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration,我们会发现当前向spring容器注册了PointCutAdvisor,也就是说事务是基于sprig AOP实现的

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		advisor.setAdvice(transactionInterceptor());
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

  //拦截器
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor() {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

二.@Transatioal注解可开启事务管理

org.springframework.transaction.interceptor.
TransactionAttributeSourcePointcut.matches()
org.springframework.transaction.interceptor.
AbstractFallbackTransactionAttributeSource.getTransactionAttribute()
org.springframework.transaction.interceptor.
AbstractFallbackTransactionAttributeSource.computeTransactionAttribute()
org.springframework.transaction.annotation.
AnnotationTransactionAttributeSource.findTransactionAttribute()
org.springframework.transaction.annotation.
AnnotationTransactionAttributeSource.determineTransactionAttribute()
org.springframework.transaction.annotation.
SpringTransactionAnnotationParser.parseTransactionAnnotation()
1.BeanFactoryTransactionAttributeSourceAdvisor()
org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

	@Nullable
	private TransactionAttributeSource transactionAttributeSource;

	private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		@Nullable
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};

	public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
		this.transactionAttributeSource = transactionAttributeSource;
	}


	public void setClassFilter(ClassFilter classFilter) {
		this.pointcut.setClassFilter(classFilter);
	}

	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}

}

2.match()
org.springframework.transaction.interceptor.TransactionAttributeSourcePointcutTransactionAttributeSourcePointcut的match()

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

	@Override
	public boolean matches(Method method, Class<?> targetClass) {
	
	//PlatformTransactionManager,TransactionalProxy,PersistenceExceptionTranslator等基础类不会被代理
	
		if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
				PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
				PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
			return false;
		}
		//TransactionAttributeSource
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}


	@Nullable
	protected abstract TransactionAttributeSource getTransactionAttributeSource();

}

3.getTransactionAttribute()
org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// First, see if we have a cached value.
		Object cacheKey = getCacheKey(method, targetClass);
		TransactionAttribute cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			// Value will either be canonical value indicating there is no transaction attribute,
			// or an actual transaction attribute.
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
				return cached;
			}
		}
		else {
			// We need to work it out.
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			// Put it in the cache.
			if (txAttr == null) {
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
				String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
				if (txAttr instanceof DefaultTransactionAttribute) {
					((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}

4.computeTransactionAttribute()

@Transational 当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性

@Transational 当作用在接口和接口方法时则只有在使用基于接口的代理时它才会生效,也就是JDK动态代理,而不是Cglib代理

@Transational 当在 protected、private 或者默认可见性的方法上使用 @Transactional 注解时是不会生效的,也不会抛出任何异常

默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰

org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.computeTransactionAttribute()

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
        //方法是非public,直接返回为null,非public方法,事务失效
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

       // 该方法可能位于接口上,但我们需要来自目标类的属性。如果目标类为 null,则该方法将保持不变
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

       //从目标方法中获取@Trantional注解
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}
       //从目标类中获取@Trantional注解
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}

		if (specificMethod != method) {
	       
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
		
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}
	

   protected TransactionAttribute findTransactionAttribute(Method method) {
		return determineTransactionAttribute(method);
   }
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
			TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
			if (attr != null) {
				return attr;
			}
		}
		return null;
	}
	
5.parseTransactionAnnotation()
propagation 解析获取事务的传播机
isolation 解析事务的隔离级别
timeout 解析事务的超时时间
readOnly 解析当前事务是否只读
value 解析当前事务名称
rollbackFor rollbackForClassName 抛出定义的异常就回滚
noRollbackFor noRollbackForClassName 抛出定义的异常并不回滚
org.springframework.transaction.annotation.SpringTransactionAnnotationParser.parseTransactionAnnotation()
org.springframework.transaction.annotation.SpringTransactionAnnotationParser

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}
	
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
        //1.解析获取事务的传播机制
		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		//2.解析事务的隔离级别
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());
		//3.解析事务的超时时间
		rbta.setTimeout(attributes.getNumber("timeout").intValue())//4.解析当前事务是否只读
		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));
        //5.获取rollbackFor定义异常的Class对象,依次构建RollbackRuleAttribute对象存入TransactionAttribute中
		List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		//6.获取rollbackForClassName定义异常的Class对象名称,依次构建RollbackRuleAttribute对象存入TransactionAttribute中
		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		//7.获取noRollbackFor定义异常的Class对象,依次构建NoRollbackRuleAttribute对象存入TransactionAttribute中
		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		//8.根据noRollbackForClassName定义异常的Class对象名字,依次构建NoRollbackRuleAttribute对象存入TransactionAttribute中
		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		rbta.setRollbackRules(rollbackRules);
		return rbta;
	}

三.spring事务原理

1.invokeWithinTransaction()
org.springframework.transaction.interceptor.TransactionInterceptor.invoke()

org.springframework.transaction.interceptor.TransactionInterceptor

public Object invoke(MethodInvocation invocation) throws Throwable {
		// Work out the target class: may be {@code null}.
		// The TransactionAttributeSource should be passed the target class
		// as well as the method, which may be from an interface.
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}
	
org.springframework.transaction.interceptor.TransactionInterceptor.invokeWithinTransaction()

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);
		//获取被拦截的方法名
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// 获取当前的事物信息,如果有需要的话会新建事务
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				//执行被拦截方法的逻辑
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// 抛出异常需要执行的逻辑,根据异常匹配注解属性的结果,选择rollback回滚(标记回滚)或者提交
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
			    //无论是否有异常都必须要执行的逻辑
				cleanupTransactionInfo(txInfo);
			}
			//未抛出异常最后需要执行的逻辑
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}
	}
2.createTransactionIfNecessary()
点击展开代码 org.springframework.transaction.interceptor.TransactionInterceptor.createTransactionIfNecessary()
 protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

		// If no name specified, apply method identification as transaction name.
		if (txAttr != null && txAttr.getName() == null) {
			txAttr = new DelegatingTransactionAttribute(txAttr) {
				@Override
				public String getName() {
					return joinpointIdentification;
				}
			};
		}

		TransactionStatus status = null;
		if (txAttr != null) {
			if (tm != null) {
			    //tm =>org.springframework.jdbc.datasource.DataSourceTransactionManager,上一章节整个章节都是讲这个方法
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}
	
点击展开代码 org.springframework.transaction.interceptor.TransactionInterceptor.prepareTransactionInfo()

protected TransactionInfo prepareTransactionInfo (@Nullable PlatformTransactionManager tm,
                @Nullable TransactionAttribute txAttr, String joinpointIdentification,
                @Nullable TransactionStatus status){

            TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
            if (txAttr != null) {
                // We need a transaction for this method...
                if (logger.isTraceEnabled()) {
                    logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
                }
                // The transaction manager will flag an error if an incompatible tx already exists.
                txInfo.newTransactionStatus(status);
            } else {
                // The TransactionInfo.hasTransaction() method will return false. We created it only
                // to preserve the integrity of the ThreadLocal stack maintained in this class.
                if (logger.isTraceEnabled()) {
                    logger.trace("No need to create transaction for [" + joinpointIdentification +
                            "]: This method is not transactional.");
                }
            }

            // We always bind the TransactionInfo to the thread, even if we didn't create
            // a new transaction here. This guarantees that the TransactionInfo stack
            // will be managed correctly even if no transaction was created by this aspect.
            txInfo.bindToThread();
            return txInfo;
        }
org.springframework.transaction.interceptor.TransactionAspectSupport

private static final ThreadLocal<TransactionInfo> transactionInfoHolder =  new NamedThreadLocal<>("Current aspect-driven transaction");

private void bindToThread() {
           //设置oldTransactionInfo为当前transactionInfoHolder的值后设置新值
			this.oldTransactionInfo = transactionInfoHolder.get();
			transactionInfoHolder.set(this);
}

3.completeTransactionAfterThrowing()
org.springframework.transaction.interceptor.TransactionInterceptor.completeTransactionAfterThrowing()
protected void completeTransactionAfterThrowing (@Nullable TransactionInfo txInfo, Throwable ex){
            if (txInfo != null && txInfo.getTransactionStatus() != null) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
                            "] after exception: " + ex);
                }
                if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
                    try {
                        txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
                    } catch (TransactionSystemException ex2) {
                        logger.error("Application exception overridden by rollback exception", ex);
                        ex2.initApplicationException(ex);
                        throw ex2;
                    } catch (RuntimeException | Error ex2) {
                        logger.error("Application exception overridden by rollback exception", ex);
                        throw ex2;
                    }
                } else {
                    // We don't roll back on this exception.
                    // Will still roll back if TransactionStatus.isRollbackOnly() is true.
                    try {
                        txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
                    } catch (TransactionSystemException ex2) {
                        logger.error("Application exception overridden by commit exception", ex);
                        ex2.initApplicationException(ex);
                        throw ex2;
                    } catch (RuntimeException | Error ex2) {
                        logger.error("Application exception overridden by commit exception", ex);
                        throw ex2;
                    }
                }
            }
        }


3.1 rollbackOn 判断是否回滚 org.springframework.transaction.interceptor.RuleBasedTransactionAttribute.rollbackOn(ex)

通过rollbackFor或者rollbackForClassName定义的异常能正好是当前异常者是当前异常的父异常,祖宗异常,则回滚


//txInfo.transactionAttribute.rollbackOn(ex)

public boolean rollbackOn(Throwable ex) 
		if (logger.isTraceEnabled()) {
			logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
		}

		RollbackRuleAttribute winner = null;
		int deepest = Integer.MAX_VALUE;
         // this.rollbackRules 解析@Transational根据rollbackFor,rollbackForClassName,noRollbackFor,noRollbackForClassName定义四个属性值解析
		if (this.rollbackRules != null) {
			for (RollbackRuleAttribute rule : this.rollbackRules) {
				int depth = rule.getDepth(ex);
				//depth<=0 表示不匹配
				if (depth >= 0 && depth < deepest) {
					deepest = depth;
					winner = rule;
				}
			}
		}

		if (logger.isTraceEnabled()) {
			logger.trace("Winning rollback rule is: " + winner);
		}

		// User superclass behavior (rollback on unchecked) if no rule matches.
		if (winner == null) {
			logger.trace("No relevant rollback rule found: applying default rules");
			return super.rollbackOn(ex);
		}

		return !(winner instanceof NoRollbackRuleAttribute);
	}


org.springframework.transaction.interceptor.RollbackRuleAttribute

public int getDepth(Throwable ex) {
		return getDepth(ex.getClass(), 0);
	}


	private int getDepth(Class<?> exceptionClass, int depth) {
		if (exceptionClass.getName().contains(this.exceptionName)) {
			// Found it!
			return depth;
		}
		// If we've gone as far as we can go and haven't found it...
		//Throwable是所有异常的祖宗类,如果还没匹配到,说明当前抛出异常不匹配,当前的类
		if (exceptionClass == Throwable.class) {
			return -1;
		}
		return getDepth(exceptionClass.getSuperclass(), depth + 1);
	}

3.2 rollback 回滚/标记回滚
rollbck
获取TransactionSynchronizationManager.getSynchronizations()
遍历TransactionSynchronizationManager对象
执行TransactionSynchronization.beforeCompletion()
2.根据事务的不同情况选择回滚或者标记回滚
如果使用了Savepoint技术,回滚嵌套事务
如果执行当前方法新建了事务,那么就直接回滚
如果执行当前方法是以事务运行,但是和其他方法共用这个事务
获取DefaultTransactionStatus属性rollbackOnly(默认false)
PlatformTransactionManager.globalRollbackOnParticipationFailure属性(默认为true)
globalRollbackOnParticipationFailure属性可以在构建PlatformTransactionManager对象时修改
globalRollbackOnParticipationFailure和rollbackOnly两者任何为true,事务会标记为回滚,否则交给事务发起方
3.triggerAfterCompletion)
<遍历执行TransactionSynchronization.afterCompletion()
并清空存储TransactionSynchronization的ThreadLocal变量synchronizations
cleanupAfterCompletion
清空有关当前ThreaLocal变量,恢复把挂起的事务,重新赋值threadLocal

org.springframework.transaction.PlatformTransactionManager.rollback()

public final void rollback(TransactionStatus status) throws TransactionException {
		if (status.isCompleted()) {
			throw new IllegalTransactionStateException(
					"Transaction is already completed - do not call commit or rollback more than once per transaction");
		}

		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
		processRollback(defStatus, false);
	}

private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
		try {
			boolean unexpectedRollback = unexpected;

			try {
				triggerBeforeCompletion(status);

				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Rolling back transaction to savepoint");
					}
					status.rollbackToHeldSavepoint();
				}
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction rollback");
					}
					//真的回滚
					doRollback(status);
				}
				else {
					// Participating in larger transaction
					if (status.hasTransaction()) {
						if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
							if (status.isDebug()) {
								logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
							}
							//标记为回滚
							doSetRollbackOnly(status);
						}
						else {
							if (status.isDebug()) {
								logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
							}
						}
					}
					else {
						logger.debug("Should roll back transaction but cannot - no transaction available");
					}
					// Unexpected rollback only matters here if we're asked to fail early
					if (!isFailEarlyOnGlobalRollbackOnly()) {
						unexpectedRollback = false;
					}
				}
			}
			catch (RuntimeException | Error ex) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				throw ex;
			}

			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

			// Raise UnexpectedRollbackException if we had a global rollback-only marker
			if (unexpectedRollback) {
				throw new UnexpectedRollbackException(
						"Transaction rolled back because it has been marked as rollback-only");
			}
		}
		finally {
			cleanupAfterCompletion(status);
		}
	}

3.2.1 triggerBeforeCompletion
org.springframework.transaction.PlatformTransactionManager.triggerBeforeCompletion
//org.springframework.transaction.PlatformTransactionManager
protected final void triggerBeforeCompletion(DefaultTransactionStatus status) {
		if (status.isNewSynchronization()) {
			if (status.isDebug()) {
				logger.trace("Triggering beforeCompletion synchronization");
			}
			TransactionSynchronizationUtils.triggerBeforeCompletion();
		}
	}

//org.springframework.transaction.support.TransactionSynchronizationUtils

public static void triggerBeforeCompletion() {
		for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
			try {
				synchronization.beforeCompletion();
			}
			catch (Throwable tsex) {
				logger.error("TransactionSynchronization.beforeCompletion threw exception", tsex);
			}
		}
	}

3.2.2 doRollback 回滚
org.springframework.transaction.support.AbstractPlatformTransactionManager.doRollback()

protected void doRollback(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject)status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        if (status.isDebug()) {
            this.logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
        }

        try {
            con.rollback();
        } catch (SQLException var5) {
            throw new TransactionSystemException("Could not roll back JDBC transaction", var5);
        }
    }

3.2.3 doSetRollbackOnly 标记回滚
org.springframework.jdbc.datasource.DataSourceTransactionManager.doSetRollbackOnly()
org.springframework.jdbc.datasource.DataSourceTransactionManager

protected void doSetRollbackOnly(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject)status.getTransaction();
        if (status.isDebug()) {
            this.logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() + "] rollback-only");
        }

        txObject.setRollbackOnly();
    }
    
//不标记来源,自行观看
 public void setRollbackOnly() {
  this.getConnectionHolder().setRollbackOnly();
 }
//不标记来源,自行观看
 public void setRollbackOnly() {
 this.rollbackOnly = true;
 }

3.2.4 triggerAfterCompletion
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion()

private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) {
		if (status.isNewSynchronization()) {
			List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
			TransactionSynchronizationManager.clearSynchronization();
			if (!status.hasTransaction() || status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.trace("Triggering afterCompletion synchronization");
				}
				// No transaction or new transaction for the current scope ->
				// invoke the afterCompletion callbacks immediately
				invokeAfterCompletion(synchronizations, completionStatus);
			}
			else if (!synchronizations.isEmpty()) {
				// Existing transaction that we participate in, controlled outside
				// of the scope of this Spring transaction manager -> try to register
				// an afterCompletion callback with the existing (JTA) transaction.
				registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations);
			}
		}
	}

protected void registerAfterCompletionWithExistingTransaction(
			Object transaction, List<TransactionSynchronization> synchronizations) throws TransactionException {

		logger.debug("Cannot register Spring after-completion synchronization with existing transaction - " +
				"processing Spring after-completion callbacks immediately, with outcome status 'unknown'");
		invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_UNKNOWN);
	}
	

protected final void invokeAfterCompletion(List<TransactionSynchronization> synchronizations, int completionStatus) {
		TransactionSynchronizationUtils.invokeAfterCompletion(synchronizations, completionStatus);
	}


//org.springframework.transaction.support.TransactionSynchronizationUtils.TransactionSynchronizationUtils.invokeAfterCompletion

public static void invokeAfterCompletion(@Nullable List<TransactionSynchronization> synchronizations,
			int completionStatus) {

		if (synchronizations != null) {
			for (TransactionSynchronization synchronization : synchronizations) {
				try {
					synchronization.afterCompletion(completionStatus);
				}
				catch (Throwable tsex) {
					logger.error("TransactionSynchronization.afterCompletion threw exception", tsex);
				}
			}
		}
	}

3.2.5 cleanupAfterCompletion()
org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion()
cleanupAfterCompletion
事务的threadLocal变量清空
重置数据库连接隔离级别和autocommit属性,并释放数据库连接
恢复挂起的资源,同时更新其他有关事务的threadlocal数据
调用synchronization.resume(),并把synchronization到对应的threadLocal变量中
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		status.setCompleted();
		if (status.isNewSynchronization()) {
		    //事务的threadLocal变量清空
			TransactionSynchronizationManager.clear();
		}
		if (status.isNewTransaction()) {
		    //重置数据库连接并释放数据库连接
			doCleanupAfterCompletion(status.getTransaction());
		}
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction after completion of inner transaction");
			}
			Object transaction = (status.hasTransaction() ? status.getTransaction() : null); 
			// 恢复挂起的资源,也就是以之前挂起资源的datasource为key,数据库连接为value,重新放入对应的threadlocal。同时更新其他有关事务的threadlocal数据。数据并且调用synchronization.resume();synchronization到对应的threadLocal变量中
			resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}

//org.springframework.transaction.support.TransactionSynchronizationManager

public static void clear() {
		synchronizations.remove();
		currentTransactionName.remove();
		currentTransactionReadOnly.remove();
		currentTransactionIsolationLevel.remove();
		actualTransactionActive.remove();
	}

//org.springframework.jdbc.datasource.DataSourceTransactionManager

DataSourceTransactionObject txObject = (DataSourceTransactionObject)transaction;
        if (txObject.isNewConnectionHolder()) {
            TransactionSynchronizationManager.unbindResource(this.obtainDataSource());
        }

        Connection con = txObject.getConnectionHolder().getConnection();

        try {
            if (txObject.isMustRestoreAutoCommit()) {
                con.setAutoCommit(true);
            }

            DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
        } catch (Throwable var5) {
            this.logger.debug("Could not reset JDBC Connection after transaction", var5);
        }

        if (txObject.isNewConnectionHolder()) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
            }

            DataSourceUtils.releaseConnection(con, this.dataSource);
        }

        txObject.getConnectionHolder().clear();


protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
			throws TransactionException {

		if (resourcesHolder != null) {
			Object suspendedResources = resourcesHolder.suspendedResources;
			if (suspendedResources != null) {
				doResume(transaction, suspendedResources);
			}
			List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
			if (suspendedSynchronizations != null) {
				TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
				TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
				TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
				doResumeSynchronization(suspendedSynchronizations);
			}
		}
	}
	
	 protected void doResume(@Nullable Object transaction, Object suspendedResources) {
        TransactionSynchronizationManager.bindResource(this.obtainDataSource(), suspendedResources);
    }
	
   private void doResumeSynchronization(List<TransactionSynchronization> suspendedSynchronizations) {
		TransactionSynchronizationManager.initSynchronization();
		for (TransactionSynchronization synchronization : suspendedSynchronizations) {
			synchronization.resume();
			TransactionSynchronizationManager.registerSynchronization(synchronization);
		}
	}
	
		public static void registerSynchronization(TransactionSynchronization synchronization)
			throws IllegalStateException {

		Assert.notNull(synchronization, "TransactionSynchronization must not be null");
		Set<TransactionSynchronization> synchs = synchronizations.get();
		if (synchs == null) {
			throw new IllegalStateException("Transaction synchronization is not active");
		}
		synchs.add(synchronization);
	}


3.3 commit() 提交
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit()

public final void commit(TransactionStatus status) throws TransactionException {
		if (status.isCompleted()) {
			throw new IllegalTransactionStateException(
					"Transaction is already completed - do not call commit or rollback more than once per transaction");
		}

		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
		if (defStatus.isLocalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Transactional code has requested rollback");
			}
			processRollback(defStatus, false);
			return;
		}

		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
			}
			processRollback(defStatus, true);
			return;
		}

		processCommit(defStatus);
	}


org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit()

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
		try {
			boolean beforeCompletionInvoked = false;

			try {
				boolean unexpectedRollback = false;
				prepareForCommit(status);
				triggerBeforeCommit(status);
				triggerBeforeCompletion(status);
				beforeCompletionInvoked = true;

				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Releasing transaction savepoint");
					}
					unexpectedRollback = status.isGlobalRollbackOnly();
					status.releaseHeldSavepoint();
				}
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction commit");
					}
					unexpectedRollback = status.isGlobalRollbackOnly();
					doCommit(status);
				}
				else if (isFailEarlyOnGlobalRollbackOnly()) {
					unexpectedRollback = status.isGlobalRollbackOnly();
				}

				// Throw UnexpectedRollbackException if we have a global rollback-only
				// marker but still didn't get a corresponding exception from commit.
				if (unexpectedRollback) {
					throw new UnexpectedRollbackException(
							"Transaction silently rolled back because it has been marked as rollback-only");
				}
			}
			catch (UnexpectedRollbackException ex) {
				// can only be caused by doCommit
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
				throw ex;
			}
			catch (TransactionException ex) {
				// can only be caused by doCommit
				if (isRollbackOnCommitFailure()) {
					doRollbackOnCommitException(status, ex);
				}
				else {
					triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				}
				throw ex;
			}
			catch (RuntimeException | Error ex) {
				if (!beforeCompletionInvoked) {
					triggerBeforeCompletion(status);
				}
				doRollbackOnCommitException(status, ex);
				throw ex;
			}

			// Trigger afterCommit callbacks, with an exception thrown there
			// propagated to callers but the transaction still considered as committed.
			try {
				triggerAfterCommit(status);
			}
			finally {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
			}

		}
		finally {
			cleanupAfterCompletion(status);
		}
	}


commit
1.synchronization.beforeCommit
2.synchronization.beforeCompletion
3.使用了savepoint,释放savepoint
4.在执行当前方法前新建了事物,就会数据库直接提交事务
前面步骤如果异常
抛出UnexpectedRollbackException
调用synchronization.afterCompletion()
cleanupAfterCompletion()恢复挂起的事务连接
TransactionException
rollbackOnCommitFailurer如果为true,回滚/标记回滚
调用synchronization.afterCompletion()
cleanupAfterCompletion()恢复挂起的事务连接
RuntimeException | Error ex
当前流程没有执行ynchronization.beforeCompletion,则执行
rollbackOnCommitFailurer如果为true,回滚/标记回滚
调用synchronization.afterCompletion()
cleanupAfterCompletion()恢复挂起的事务连接
无任何异常
synchronization.afterCommit()
synchronization.afterCompletion()
cleanupAfterCompletion()恢复挂起的事务连接
3.3.1 prepareForCommit()
org.springframework.transaction.support.AbstractPlatformTransactionManager.prepareForCommit()

protected void prepareForCommit(DefaultTransactionStatus status) {	}

3.3.2 triggerBeforeCommit() 调用TransactionSynchronization调用TransactionSynchronization.beforeCommit()方法
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit()

protected final void triggerBeforeCommit(DefaultTransactionStatus status) {
		if (status.isNewSynchronization()) {
			if (status.isDebug()) {
				logger.trace("Triggering beforeCommit synchronization");
			}
			TransactionSynchronizationUtils.triggerBeforeCommit(status.isReadOnly());
		}
	}
	
	// org.springframework.transaction.support.TransactionSynchronizationUtils
	public static void triggerBeforeCommit(boolean readOnly) {
		for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
			synchronization.beforeCommit(readOnly);
		}
	}

3.3.3 triggerBeforeCompletion()调用TransactionSynchronization.beforeCompletion()方法
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit()

protected final void triggerBeforeCompletion(DefaultTransactionStatus status) {
		if (status.isNewSynchronization()) {
			if (status.isDebug()) {
				logger.trace("Triggering beforeCompletion synchronization");
			}
			TransactionSynchronizationUtils.triggerBeforeCompletion();
		}
	}
	
	// org.springframework.transaction.support.TransactionSynchronizationUtils
	public static void triggerBeforeCompletion() {
		for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
			try {
				synchronization.beforeCompletion();
			}
			catch (Throwable tsex) {
				logger.error("TransactionSynchronization.beforeCompletion threw exception", tsex);
			}
		}
	}

3.3.4 doCommit()提交事务
org.springframework.transaction.support.AbstractPlatformTransactionManager.doCommit()

protected void doCommit(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject)status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        if (status.isDebug()) {
            this.logger.debug("Committing JDBC transaction on Connection [" + con + "]");
        }

        try {
            con.commit();
        } catch (SQLException var5) {
            throw new TransactionSystemException("Could not commit JDBC transaction", var5);
        }
    }

3.3.5 triggerAfterCompletion()提交事务
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion()

private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) {
		if (status.isNewSynchronization()) {
			List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
			TransactionSynchronizationManager.clearSynchronization();
			if (!status.hasTransaction() || status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.trace("Triggering afterCompletion synchronization");
				}
				// No transaction or new transaction for the current scope ->
				// invoke the afterCompletion callbacks immediately
				invokeAfterCompletion(synchronizations, completionStatus);
			}
			else if (!synchronizations.isEmpty()) {
				// Existing transaction that we participate in, controlled outside
				// of the scope of this Spring transaction manager -> try to register
				// an afterCompletion callback with the existing (JTA) transaction.
				registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations);
			}
		}
	}


protected final void invokeAfterCompletion(List<TransactionSynchronization> synchronizations, int completionStatus) {
		TransactionSynchronizationUtils.invokeAfterCompletion(synchronizations, completionStatus);
	}	

//org.springframework.transaction.support.TransactionSynchronizationUtils

public static void invokeAfterCompletion(@Nullable List<TransactionSynchronization> synchronizations,
			int completionStatus) {

		if (synchronizations != null) {
			for (TransactionSynchronization synchronization : synchronizations) {
				try {
					synchronization.afterCompletion(completionStatus);
				}
				catch (Throwable tsex) {
					logger.error("TransactionSynchronization.afterCompletion threw exception", tsex);
				}
			}
		}
	}
	

3.3.6 doRollbackOnCommitException() 回滚并且调用synchronization.afterCompletion()方法
org.springframework.transaction.support.AbstractPlatformTransactionManager.doRollbackOnCommitException()

private void doRollbackOnCommitException(DefaultTransactionStatus status, Throwable ex) throws TransactionException {
		try {
			if (status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.debug("Initiating transaction rollback after commit exception", ex);
				}
				//回滚
				doRollback(status);
			}
			else if (status.hasTransaction() && isGlobalRollbackOnParticipationFailure()) {
				if (status.isDebug()) {
					logger.debug("Marking existing transaction as rollback-only after commit exception", ex);
				}
				//标记回滚
				doSetRollbackOnly(status);
			}
		}
		catch (RuntimeException | Error rbex) {
			logger.error("Commit exception overridden by rollback exception", ex);
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
			throw rbex;
		}
		//执行synchronization.afterCompletion()
		triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
	}

3.3.7 triggerAfterCommit()调用synchronization.afterCommit()方法
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCommit()

private void triggerAfterCommit(DefaultTransactionStatus status) {
		if (status.isNewSynchronization()) {
			if (status.isDebug()) {
				logger.trace("Triggering afterCommit synchronization");
			}
			TransactionSynchronizationUtils.triggerAfterCommit();
		}
	}
	
//org.springframework.transaction.support.TransactionSynchronizationUtils	
	
public static void triggerAfterCommit() {
		invokeAfterCommit(TransactionSynchronizationManager.getSynchronizations());
	}

public static void invokeAfterCommit(@Nullable List<TransactionSynchronization> synchronizations) {
		if (synchronizations != null) {
			for (TransactionSynchronization synchronization : synchronizations) {
				synchronization.afterCommit();
			}
		}
	}
4.cleanupTransactionInfo() 恢复之前的TransactionInfo
org.springframework.transaction.interceptor.TransactionAspectSupport.cleanupTransactionInfo()
protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {
		if (txInfo != null) {
			txInfo.restoreThreadLocalStatus();
		}
	}
	
	//org.springframework.transaction.interceptor.TransactionAspectSupport
	
		private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
			new NamedThreadLocal<>("Current aspect-driven transaction");
			
	private void restoreThreadLocalStatus() {
			// Use stack to restore old transaction TransactionInfo.
			// Will be null if none was set.
			transactionInfoHolder.set(this.oldTransactionInfo);
		}

5.commitTransactionAfterReturning
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning()
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
			}
			//展开上面的 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit()逻辑
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值