从源码看Spring事务

       通过上一篇《从@Transactional注解看Spring事务》,已经大概了解了事务中的基本使用。这一篇,小编跟大家一起通过Spring中几个重要源码类来增加对Spring事务的了解;

      在Spring中实现事务需要很多类的配合,但这里小编主要分析这几个类:TransactionDefinition、PlatformTransactionManager、TransactionStatus、TransactionInceptor;

▶  TransactionDefinition

      从字面上来看,这个类主要是做事务的定义。实际上也确实是这样,它是对事务定义的最顶级接口,主要是定义事务隔离级别、事务传播性和事务的只读性等。

     TransactionDefinition部分代码:

public interface TransactionDefinition {

	int PROPAGATION_REQUIRED = 0;

	int PROPAGATION_SUPPORTS = 1;

	int PROPAGATION_REQUIRES_NEW = 3;

	int PROPAGATION_NOT_SUPPORTED = 4;

	int PROPAGATION_NEVER = 5;

	int PROPAGATION_NESTED = 6;

	int ISOLATION_DEFAULT = -1;

	int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;

	int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;

	int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;

	int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;

	int TIMEOUT_DEFAULT = -1;

	// 获取事务的隔离级别
	int getPropagationBehavior();

	//获取隔离级别
	int getIsolationLevel();

	//是否超时
	int getTimeout();

	//校验当前事务是只读
	boolean isReadOnly();

	@Nullable
	String getName();

}

结合类(接口)与类(接口)之间的关系,小编整理出来一张图,用来明确TransactionDefinition这个接口不可撼动的地位:

       从上图中,我们可以看到在实现TranscationDefinition这个接口的有DefaultTransactionDefinition类,在这个类中,对TransactionDefinition中的方法进行简单实现;

▶ PlatformTransactionManager

    和TransactionDefinition一样,都是接口,并且都是在自己的领域内的顶级接口;PlatformTransactionManager是事务管理器的顶级接口,各持久化框架要想接入spring的事务管理,都必须自行提供该接口的实现。

实现PlatformTransactionManager接口的类列表

      在这个接口的众多实现类中,有一个不容忽视的类AbstractPlatformTransactionManager;

      为什么说它不容忽视呢?在这个类中实现了spring标准的事务流

类图

   综合上图我们很容易得知,在该类中,定义并实现了很多与事务直接相关的方法,在该类中,除了对PlatformTransactionManager中commit(TransactionStatus status),rollback(TransactionStatus status),getTransaction(@Nullable TransactionDefinition definition)三个方法进行重载之外,定义了许多 **TransactionSynchronization、**ValidateExistingTranscation*、**rollbackOnCommitFailure、handleExistingTransaction等的私有或受保护的方法;这些方法覆盖了事务状态、对存在的事务的有效性和处理、提交失败的事务处理等方面,正因为如此,才会在上文中提到“在这个类中实现了spring标准的事务流”;

 ☞ getTransaction(TransactionDefinition definition):只要是对事务传播行为的处理

@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
	Object transaction = doGetTransaction();

	// Cache debug flag to avoid repeated checks.
	boolean debugEnabled = logger.isDebugEnabled();

    //如果传入的事务定义为空,则初始化一个DefaultTransactionDefinition类
	if (definition == null) {
		// Use defaults if no transaction definition given.
		definition = new DefaultTransactionDefinition();
	}

    //如果已经存在事务,调用方法处理当前存在的事务
	if (isExistingTransaction(transaction)) {
		// Existing transaction found -> check propagation behavior to find out how to behave.
		return handleExistingTransaction(definition, transaction, debugEnabled);
	}

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

	// No existing transaction found -> check propagation behavior to find out how to proceed.
	if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
		throw new IllegalTransactionStateException(
				"No existing transaction found for transaction marked with propagation 'mandatory'");
	}
	else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
			definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
			definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
		SuspendedResourcesHolder suspendedResources = suspend(null);
		if (debugEnabled) {
			logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
		}
		try {
			boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
			DefaultTransactionStatus status = newTransactionStatus(
					definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
			doBegin(transaction, definition);
			prepareSynchronization(status, definition);
			return status;
		}
		catch (RuntimeException | Error ex) {
			resume(null, suspendedResources);
			throw ex;
		}
	}
	else {
		// Create "empty" transaction: no actual transaction, but potentially synchronization.
		if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
			logger.warn("Custom isolation level specified but no actual transaction initiated; " +
					"isolation level will effectively be ignored: " + definition);
		}
		boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
		return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
	}
}

在方法实现的最后,prepareTransactionStatus方法需要引起我们的注意,最终该方法会调用到一个同名方法:

/**
* status.isNewSynchronization是判断一个新的事务锁定是否已经开启;
*/
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
			TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
					definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
							definition.getIsolationLevel() : null);
			TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
			TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
			TransactionSynchronizationManager.initSynchronization();
		}
}

     因此,getTransaction方法其实就是对我们平时对事务设置的传播行为进行的分析和处理。{提前透漏,该方法是事务实现的直接被调用方,稍后会讲到}

☞ commit(TransactionStatus status):

@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;
	}
	//将事务的当前状态,提交事务
	processCommit(defStatus);
}

当我们使用编程式事务时手动提交事务的实现就是这个commit方法,它的作用,要么提交当前事务,要么回滚;

其中,defStatus.isLocalRollbackOnly()变量的实际值:是根据事务传播行为的不同而具备的回滚当前事务或者整个事务的flag;举个栗子,nested事务,回滚的是当前事务,而不影响整体的事务流程;required事务,则表示要回滚的是整个事务流程;

☞ rollback:

该方法的实现逻辑使用伪代码来表示为:

· 是否有节点
   有--回滚到当前保存的事务节点
· 是否为新事务
   是--回滚当前事务
·  其他情况
   · 是否有事务
   ……

因此,该方法和commit方法是相辅相承的。

☞ handleExistingTransaction :该方法主要是为一个存在的事务创建事务状态;

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);
	}
	//事务隔离级别为开启一个新事务
	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 {
			boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
			DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
			doBegin(transaction, definition);
			prepareSynchronization(status, definition);
			return status;
		}
		catch (RuntimeException | Error beginEx) {
			resumeAfterBeginException(transaction, suspendedResources, beginEx);
			throw beginEx;
		}
	}
	//事务隔离级别为嵌套事务
	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.
			boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
			DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, true, newSynchronization, debugEnabled, null);
			doBegin(transaction, definition);
			prepareSynchronization(status, definition);
			return status;
		}
	}

	// 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);
}

▶ TransactionTemplate

        该类继承了DefaultTransactionDefinition,简化了事务的划分和事务异常的处理;在该类中,引用了PlatformTransactionManager,核心方法是execute:

@Override
@Nullable
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
	Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");

    //如果实现了CallbackPreferringPlatformTransactionManager,直接调用execute方法(由于execute方法的出参是泛型,必须有具体类做强转)
	if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
		return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
	}
	else {
    //如果不是,获取当前事务管理器的事务状态
		TransactionStatus status = this.transactionManager.getTransaction(this);
		T result;
		try {
            // 这个方法我还没有明确调用关系,待后续!!!!!!!
			result = action.doInTransaction(status);
		}
		catch (RuntimeException | Error ex) {
			// Transactional code threw application exception -> rollback
			rollbackOnException(status, ex);
			throw ex;
		}
		catch (Throwable ex) {
			// Transactional code threw unexpected exception -> rollback
			rollbackOnException(status, ex);
			throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
		}
		this.transactionManager.commit(status);
		return result;
	}
}

▶TransactionStatus:

       表示事务的状态,代表一个新建的或者已经存在的事务,控制事务执行和查询事务状态;它是从SavePointManager接口派生的,但需要注意的是:节点管理只对基础的事务管理起作用;

▶ TransactionInterceptor

       我们都知道Spring的事务是采用AOP(切面)的方式实现的,提起事务实现我们就不得不提及到TransactionAspectSupport和它的相关类;

       TransactionAspectSupport是提供事务切面的抽象类(也可以理解成是一个基础类,比如TransactionInterceptor),该类包括spring的基础事务api;

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {

        该类实现了BeanFactoryAware和InitializingBean,在该类所定义的每一个方法都有自己的实现,但由于要做切面,它的子类都必须序列化,否则无法使用,因此该类是抽象的;

       该类实现的BeanFactoryAware的作用,主要是为了能够使用spring中的bean做配置:

public interface BeanFactoryAware extends Aware {
  void setBeanFactory(BeanFactory var1) throws BeansException;
}

     该类中实现的InitializingBean,主要是在bean实例化完成后调用,完成初始化检查,查看当前对象是否完整,是否可用;而对对象的可用性检查则是在afterPropertiesSet方法中完成;

public interface InitializingBean {
  void afterPropertiesSet() throws Exception;
}

     作为TransactionAspectSupport的子类,是线程安全的,它按照正确的顺序调用了超类中的方法(比如:invokeWithinTransaction):

@Override
@Nullable
public Object invoke(final 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);  //此处调用为超类中的方法
}


TransactionAspectSupport.invokeWithinTransaction 代码如下:

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();
    //根据事务属性源,获取事务属性(属性是配置的,详见setTransactionAttributes(Properties transactionAttributes)方法)
	final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    // 获取事务属性要使用的事务管理器
	final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    //获取方法标识,为子类的切面提供调用条件
	final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

    //如果事务属性是空,或者并不是CallbackPreferringPlatformTransactionManager的实现类
    //该种情况通常是我们使用的声明式事务的执行逻辑
	if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
		// Standard transaction demarcation with getTransaction and commit/rollback calls.
        //根据事务属性、节点定义信息和事务管理器创建事务
		TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
		Object retVal = null;
		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 {
			cleanupTransactionInfo(txInfo);
		}
		commitTransactionAfterReturning(txInfo);
		return retVal;
	}
    // 编程式事务的执行逻辑
	else {
		final ThrowableHolder throwableHolder = new ThrowableHolder();

		// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
		try {
			Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
				TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
				try {
					return invocation.proceedWithInvocation();
				}
				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);
				}
			});

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

    该篇主要是先对Spring事务中的几个重要类(接口)有个大致的了解,后续将会对它们在Spring事务中的协作进行深入解析;

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值