spring 事务源码剖析

阅读前准备工作:

  • 简单了解 spring AOP 的实现原理
  • JDK8 & spring 5.2.X 源码解读

0.前言

  • 初学时,spring的事务怎么实现的,为什么一个@Transactional注解就能搞定那么复杂的事务管理?
  • 搬砖时,为什么有时候我明明加了@Transactional注解,但是事务就是没有生效?
  • 面试时,面试官:说说spring的事务传播机制是怎样的?

你是否遇到过这样的问题?
你能解答上来吗?

带着这3个问题我们进入今天的主题:spring的事务管理。

注意:我们只站在spring这个框架设计者的角度讨论,讨论的是如何抽象和设计出一套事务管理机制,让开发者用起来很方便。

0.1 查缺补漏

先以JDBC为例,简写一个,看看没有spring的事务管理机制,我们自己需要怎么处理:

public void insertIntoDb(Student s) {
        Connection con = JdbcUtils.getConnection();
        try {
            con.setAutoCommit(false);//开启事务
            
            // 执行插入到数据库的逻辑
            
            con.commit();//try的最后提交事务
        } catchException e){
            con.rollback();
            //如果需要,还得根据异常类型来判断要不要回滚事务
        }
    }

我们简单写一个spring的声明式事务,看看开发过程中是怎么使用的:

    @Transactional
    public void insertIntoDb(Student s) {
        // 执行插入到数据库的逻辑
    }

前后对比之下,大大的简化了开发,这也是spring框架设计者的初衷,让业务开发者专注于业务,将通用的,复杂的公共逻辑交给spring来抽象和设计。

好了,话不多说,进入源码的分析。

0.2 怎么查看源码

对于spring不是特别熟悉的人来说,就有一个问题,怎么找源码的入口?从哪里开始看呢?

其实简单,摁住Transactional注解点进去源码,会看到:

在这里插入图片描述

然后,鼠标如图放在这个注解上,继续点进去,会看到:

在这里插入图片描述

这里很明显,有用的源码只剩下一个类,这还不简单?顺着这个思路往里跟两次调用,你就会看到:
在这里插入图片描述

如果你能跟到这里,恭喜你,你已经揭开了spring事务一半的面纱,这就是spring事务管理实际 invoke 的地方,接下来就是揭开另一半的面纱,看看这个invoke里面到底是怎么实现的就行了。

0.3 不会源码跟踪怎么办

简单,内事不决问百度,外事不决问谷歌,选择你喜欢的,搜就完了。

如果你不搜,没关系,我搜过了,大致的浏览了几个帖子,你会看到几个关键的类名:TransactionAspectSupport(看名字就知道是AOP实现的事务管理了对吧)、
TransactionInterceptor(看名字都知道是事务相关的拦截器了对吧)、AbstractTransactionManager、PlatformTransactionManager等等,

总之,你已经能定位到 TransactionInterceptor 这个类了。

找到关键地方之后,我们开始看源码。

食用前建议

先上一张调用时序图:
在这里插入图片描述

源码很长,不要直接看我所粘贴的源码和注释,建议读者和文字一起对照着看源码,才不会觉得文字冗长烦躁,最后回过头看我所粘贴的源码和注释和你所理解的是否一致即可。

源码流程很长,我这里拆分成几个部分:事务初始化创建、事务挂起、事务commit、事务回滚

1.源码解析-事务初始化创建

作为声明式事务处理实现的起始点,需要注意 TransactionInterceptor 拦截器 的 invoke()回调 中使用的 createTransactionIfNecessary()方法,这个方法是在 TransactionInterceptor 的基类 TransactionAspectSupport 中实现的。为了了解这个方法的实现,先分析一下 TransactionInterceptor 的基类实现 TransactionAspectSupport,并以这个方法的实现为入口,了解 Spring 是如何根据当前的事务状态和事务属性配置完成事务创建的。

这个 TransactionAspectSupport 的 createTransactionIfNecessary()方法 作为事务创建的入口,其具体的实现时序如下图所示。在 createTransactionIfNecessary()方法 的调用中,会向 AbstractTransactionManager 执行 getTransaction()方法,这个获取 Transaction 事务对象 的过程,在 AbstractTransactionManager 实现 中需要对事务的情况做出不同的处理,然后,创建一个 TransactionStatus,并把这个 TransactionStatus 设置到对应的 TransactionInfo 中去,同时将 TransactionInfo 和当前的线程绑定,从而完成事务的创建过程。createTransactionIfNeccessary()方法 调用中,可以看到两个重要的数据对象 TransactionStatus 和 TransactionInfo 的创建,这两个对象持有的数据是事务处理器对事务进行处理的主要依据,对这两个对象的使用贯穿着整个事务处理的全过程。

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

	@Override
	@Nullable
	/**
	 * spring的事务,会被AOP代理执行,这个 invoke 就是代理对象将会执行的方法
	 */
	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);
	}
}


public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {

    	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
											 final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		TransactionAttributeSource tas = getTransactionAttributeSource();
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		final TransactionManager tm = determineTransactionManager(txAttr);

		// 这里区分不同类型的 PlatformTransactionManager,因为他们的调用方式不同,
		// 对 CallbackPreferringPlatformTransactionManager 来说,需要回调函数
		// 来实现事务的创建和提交,而非 CallbackPreferringPlatformTransactionManager 则不需要
		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
				if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
					throw new TransactionUsageException(
							"Unsupported annotated transaction on suspending function detected: " + method +
									". Use TransactionalOperator.transactional extensions instead.");
				}
				ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
				if (adapter == null) {
					throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
							method.getReturnType());
				}
				return new ReactiveTransactionSupport(adapter);
			});
			return txSupport.invokeWithinTransaction(
					method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
		}

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

		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				retVal = invocation.proceedWithInvocation();
			} catch (Throwable ex) {
				// target invocation exception
				// 如果在事务处理方法调用中出现了异常,事务如何进行处理需要
				// 根据具体情况考虑回滚或提交
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			} finally {
				// 这里清理ThreadLocal,也就是把 与线程绑定的 TransactionInfo 设置为 oldTransactionInfo
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}

			// 在事务执行后,提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		} else {
			Object result;
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
					TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
					try {
						Object retVal = invocation.proceedWithInvocation();
						if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
							// Set rollback-only in case of Vavr failure matching our rollback rules...
							retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
						}
						return retVal;
					} catch (Throwable ex) {
						if (txAttr.rollbackOn(ex)) {
							// A RuntimeException: will lead to a rollback.
							if (ex instanceof RuntimeException) {
								throw (RuntimeException) ex;
							} else {
								throw new ThrowableHolderException(ex);
							}
						} else {
							// A normal return value: will lead to a commit.
							throwableHolder.throwable = ex;
							return null;
						}
					} finally {
						cleanupTransactionInfo(txInfo);
					}
				});
			} catch (ThrowableHolderException ex) {
				throw ex.getCause();
			} catch (TransactionSystemException ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
					ex2.initApplicationException(throwableHolder.throwable);
				}
				throw ex2;
			} catch (Throwable ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
				}
				throw ex2;
			}

			// Check result state: It might indicate a Throwable to rethrow.
			if (throwableHolder.throwable != null) {
				throw throwableHolder.throwable;
			}
			return result;
		}
	}
	
	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) {
				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);
	}

	/**
	 * Prepare a TransactionInfo for the given attribute and status object.
	 *
	 * @param txAttr                  the TransactionAttribute (may be {@code null})
	 * @param joinpointIdentification the fully qualified method name
	 *                                (used for monitoring and logging purposes)
	 * @param status                  the TransactionStatus for the current transaction
	 * @return the prepared TransactionInfo object
	 */
	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.
		// 将创建好的事务对象 TransactionInfo 设置到 ThreadLocal 里面
		txInfo.bindToThread();
		return txInfo;
	}

}

在以上的处理过程之后,可以看到,具体的事务创建可以交给事务处理器来完成。在事务的创建过程中,已经为事务的管理做好了准备,包括记录事务处理状态,以及绑定事务信息和线程等。下面到事务处理器中去了解一下更底层的事务创建过程。

并且,createTransactionIfNecessary()方法 通过调用 PlatformTransactionManager 的 getTransaction()方法,生成一个 TransactionStatus 对象,封装了底层事务对象的创建。可以看到,AbstractPlatformTransactionManager 提供了创建事务的模板,这个模板会被具体的事务处理器所使用。从下面的代码中可以看到,AbstractPlatformTransactionManager 会根据事务属性配置和当前进程绑定的事务信息,对事务是否需要创建,怎样创建 进行一些通用的处理,然后把事务创建的底层工作交给具体的事务处理器完成。尽管具体的事务处理器完成事务创建的过程各不相同,但是不同的事务处理器对事务属性和当前进程事务信息的处理都是相同的,在 AbstractPlatformTransactionManager 中完成了该实现,这个实现过程是 Spring 提供统一事务处理的一个重要部分。

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

    @Override
	public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException {

		// Use defaults if no transaction definition given.
		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

		// 模板方法设计模式,将 doGetTransaction 交给具体的子类来实现
		Object transaction = doGetTransaction();
		boolean debugEnabled = logger.isDebugEnabled();

		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			// 这个事务已存在的话,处理器传播机制等信息,用新的覆盖旧的
			return handleExistingTransaction(def, transaction, debugEnabled);
		}

		// Check definition settings for new transaction.
		if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
		}

		// No existing transaction found -> check propagation behavior to find out how to proceed.
		if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
		// 事务不存在,那么创建一个事务,
		else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
			}
			try {
				return startTransaction(def, transaction, debugEnabled, suspendedResources);
			} catch (RuntimeException | Error ex) {
				resume(null, suspendedResources);
				throw ex;
			}
		} else {
			// Create "empty" transaction: no actual transaction, but potentially synchronization.
			// 以默认的事务传播机制创建一个事务
			if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
				logger.warn("Custom isolation level specified but no actual transaction initiated; " +
						"isolation level will effectively be ignored: " + def);
			}
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
		}
	}


	protected final DefaultTransactionStatus prepareTransactionStatus(
			TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
			boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {

		DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
		prepareSynchronization(status, definition);
		return status;
	}

	/**
	 * Create a TransactionStatus instance for the given arguments.
	 */
	protected DefaultTransactionStatus newTransactionStatus(
			TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
			boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {

		// 这里判断是不是新事务,如果是新事务,需要把事务属性存放到当前线程中
		// TransactionSynchronizationManager 维护了一系列的 ThreadLocal变量
		// 来保持事务属性,比如,并发事务隔离级别,是否有活跃的事务等
		boolean actualNewSynchronization = newSynchronization &&
				!TransactionSynchronizationManager.isSynchronizationActive();
		return new DefaultTransactionStatus(
				transaction, newTransaction, actualNewSynchronization,
				definition.isReadOnly(), debug, suspendedResources);
	}
    
}

抽象类的实现:

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

	@Override
	public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException {

		// Use defaults if no transaction definition given.
		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

		// 模板方法设计模式,将 doGetTransaction 交给具体的子类来实现
		Object transaction = doGetTransaction();
		boolean debugEnabled = logger.isDebugEnabled();

		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			// 这个事务已存在的话,处理器传播机制等信息,用新的覆盖旧的
			return handleExistingTransaction(def, transaction, debugEnabled);
		}

		// Check definition settings for new transaction.
		if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
		}

		// No existing transaction found -> check propagation behavior to find out how to proceed.
		if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
		// 事务不存在,那么创建一个事务,
		else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
			}
			try {
				return startTransaction(def, transaction, debugEnabled, suspendedResources);
			} catch (RuntimeException | Error ex) {
				resume(null, suspendedResources);
				throw ex;
			}
		} else {
			// Create "empty" transaction: no actual transaction, but potentially synchronization.
			// 以默认的事务传播机制创建一个事务
			if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
				logger.warn("Custom isolation level specified but no actual transaction initiated; " +
						"isolation level will effectively be ignored: " + def);
			}
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
		}
	}

}

从上面的代码中可以看到,AbstractTransactionManager 提供的创建事务的实现模板,在这个模板的基础上,具体的事务处理器需要定义自己的实现来完成底层的事务创建工作,比如需要实现 isExistingTransaction() 和 doBegin()方法。关于这些由具体事务处理器实现的方法会在下面结合具体的事务处理器实现,如:DataSourceTransactionManager、HibernateTransactionManager 进行分析。

至此,事务的初始化创建就执行完了,但是还有一点,如果事务已存在,则会执行已存在的逻辑:

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

	private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction");
			}
			Object suspendedResources = suspend(transaction);
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}

		// 这里如果是 REQUIRES_NEW ,所以要创建新的事物,那么需要将当前事务挂起
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction, creating new transaction with name [" +
						definition.getName() + "]");
			}
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			try {
				// 挂起的事务信息也要设置到 ThreadLocal中
				return startTransaction(definition, transaction, debugEnabled, suspendedResources);
			} catch (RuntimeException | Error beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
		}

		// PROPAGATION_NESTED 表示 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
		// 则执行与 PROPAGATION_REQUIRED 类似的操作
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			if (!isNestedTransactionAllowed()) {
				throw new NestedTransactionNotSupportedException(
						"Transaction manager does not allow nested transactions by default - " +
								"specify 'nestedTransactionAllowed' property with value 'true'");
			}
			if (debugEnabled) {
				logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
			}
			if (useSavepointForNestedTransaction()) {
				// Create savepoint within existing Spring-managed transaction,
				// through the SavepointManager API implemented by TransactionStatus.
				// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
				status.createAndHoldSavepoint();
				return status;
			} else {
				// Nested transaction through nested begin and commit/rollback calls.
				// Usually only for JTA: Spring synchronization might get activated here
				// in case of a pre-existing JTA transaction.
				return startTransaction(definition, transaction, debugEnabled, null);
			}
		}

		// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
		if (debugEnabled) {
			logger.debug("Participating in existing transaction");
		}
		if (isValidateExistingTransaction()) {
			if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
				Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
					Constants isoConstants = DefaultTransactionDefinition.constants;
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] specifies isolation level which is incompatible with existing transaction: " +
							(currentIsolationLevel != null ?
									isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
									"(unknown)"));
				}
			}
			if (!definition.isReadOnly()) {
				if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] is not marked as read-only but existing transaction is");
				}
			}
		}
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}
}

2.源码解析-事务挂起

前面的源码中有调用过这个方法,直接上源码:

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

    /**
	 * 挂起给定的事务。先挂起事务同步,然后委托给 doSuspend()方法,子类一般会重写该方法。
	 * 该方法返回的 SuspendedResourcesHolder对象,会作为参数传递给 TransactionStatus
	 */
	@Nullable
	protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
			try {
				Object suspendedResources = null;
				if (transaction != null) {
					suspendedResources = doSuspend(transaction);
				}
				// 挂起的事务,需要将ThreadLocal中的变量进行标识设置
				String name = TransactionSynchronizationManager.getCurrentTransactionName();
				TransactionSynchronizationManager.setCurrentTransactionName(null);
				boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
				TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
				Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
				boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
				TransactionSynchronizationManager.setActualTransactionActive(false);
				return new SuspendedResourcesHolder(
						suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
			} catch (RuntimeException | Error ex) {
				// doSuspend failed - original transaction is still active...
				doResumeSynchronization(suspendedSynchronizations);
				throw ex;
			}
		} else if (transaction != null) {
			// Transaction active but no synchronization active.
			Object suspendedResources = doSuspend(transaction);
			return new SuspendedResourcesHolder(suspendedResources);
		} else {
			// Neither transaction nor synchronization active.
			return null;
		}
	}
}

3.源码解析-事务提交

有了前面的对事务创建的分析,下面来分析一下在 Spring 中,声明式事务处理的事务提交是如何完成的。事务提交的调用入口是 TransactionInteceptor 的 invoke()方法,事务提交的具体实现则在其基类 TransactionAspectSupport 的 commitTransactionAfterReturning(TransactionInfo txInfo)方法 中,其中的参数 txInfo 是创建事务时生成的。同时,Spring 的事务管理框架生成的 TransactionStatus 对象 就包含在 TransactionInfo 对象 中。这个 commitTransactionAfterReturning()方法 在 TransactionInteceptor 的实现部分是比较简单的,它通过直接调用事务处理器来完成事务提交。

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {

	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());
		}
	}
}
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

	@Override
	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;
		}

		// 执行提交,这个就是具体的提交逻辑了,JDBC的实现、HH2的实现,等等
		processCommit(defStatus);
	}
}

也是模板方法的设计模式,子类来执行具体的提交逻辑:

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

    /**
     * 处理实际提交的事务,这是一个模板方法,其中的 doCommit() 是一个交由子类实现的抽象方法
     */
    private void processCommit(DefaultTransactionStatus status) throws TransactionException {
        try {
            boolean beforeCompletionInvoked = false;
            try {
                // 事务提交的准备工作由具体的事务管理器来完成
                prepareForCommit(status);
                triggerBeforeCommit(status);
                triggerBeforeCompletion(status);
                beforeCompletionInvoked = true;
                boolean globalRollbackOnly = false;
                if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
                    globalRollbackOnly = status.isGlobalRollbackOnly();
                }
                // 嵌套事务的处理
                if (status.hasSavepoint()) {
                    if (status.isDebug()) {
                        logger.debug("Releasing transaction savepoint");
                    }
                    status.releaseHeldSavepoint();
                }
                // 如果当前事务是一个新事务,调用具体事务处理器的 doCommit() 实现;否则,
                // 不提交,由已经存在的事务来完成提交
                else if (status.isNewTransaction()) {
                    if (status.isDebug()) {
                        logger.debug("Initiating transaction commit");
                    }
                    // 该实现由具体的事务管理器来完成
                    doCommit(status);
                }
                // 如果我们有一个全局仅回滚标记,但仍然没有从 commit 中获得相应的异常,
                // 则抛出 UnexpectedRollbackException
                if (globalRollbackOnly) {
                    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 ex) {
                if (!beforeCompletionInvoked) {
                    triggerBeforeCompletion(status);
                }
                doRollbackOnCommitException(status, ex);
                throw ex;
            }
            catch (Error err) {
                if (!beforeCompletionInvoked) {
                    triggerBeforeCompletion(status);
                }
                doRollbackOnCommitException(status, err);
                throw err;
            }

            // 触发器 afterCommit()回调,其中抛出的异常已传播到调用方,但该事务仍被视为已提交
            try {
                triggerAfterCommit(status);
            }
            finally {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
            }

        }
        finally {
            cleanupAfterCompletion(status);
        }
    }
}

4.源码解析-事务回滚

几乎和提交的源码一模一样,只不过换成了回滚逻辑:

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

    /**
     * 处理实际的事务回滚
     */
    private void processRollback(DefaultTransactionStatus status) {
        try {
            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 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");
                }
            }
            catch (RuntimeException ex) {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
                throw ex;
            }
            catch (Error err) {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
                throw err;
            }
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
        }
        finally {
            cleanupAfterCompletion(status);
        }
    }
}

至此,spring事务管理机制,已经没有什么秘密可言了。

思考:

  • spring的事务设计对我们开发者而言,有什么参考的地方

采用模板方法设计模式,封装公共逻辑,细节和差异项的东西交给子类去实现

采用AOP对事务对象进行各种初始化操作、个性化封装,来达到事务对象的处理

将最终处理好的事务对象设置到 ThreadLocal 中,来保证一次业务调用代码能的事务

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值