Spring4.x源码分析:@Transactional注解事务

本文概要

1、@Transactional注解简单使用
2、Spring事务传播行为
3、TxNameSpaceHandler作用
4、TransactionInterceptor源码分析

Spring事务传播行为

事务传播行为指的是当一个事务方法被另一个事务方法调用时,这个事务方法的执行策略

Spring定义了7种传播行为:

  • PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
  • PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
  • PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

@Transactional注解简单使用

1、开启spring注解事务(配置事务管理器和数据源省略)

	// 前面需要配置数据源和事务管理器,这两个配置就省略了
	// 直接开启注解事务
	<tx:annotation-driven transaction-manager="transactionManager"/>

2、在service层使用@Transactional注解
在这里插入图片描述

TxNameSpaceHandler作用

我们想要知道@Transactional注解的原理,首先要知道标签的作用,标签的解析类是org.springframework.transaction.config.TxNamespaceHandler

public class TxNamespaceHandler extends NamespaceHandlerSupport {

	static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";

	static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";


	static String getTransactionManagerName(Element element) {
		return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
				element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
	}


	@Override
	public void init() {
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}

}

由上面可知,标签的解析器是AnnotationDrivenBeanDefinitionParser类,所以AnnotationDrivenBeanDefinitionParser肯定有parse方法,所以我们只看下parse方法

class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {

	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		registerTransactionalEventListenerFactory(parserContext);
		String mode = element.getAttribute("mode");
		if ("aspectj".equals(mode)) {
			// mode="aspectj"
			registerTransactionAspect(element, parserContext);
		}
		else {
			// mode="proxy"
			AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
		}
		return null;
	}
	/**
	* 其他方法省略......
	*/
	
}

首先获取mode的属性,默认情况下,mode=proxy,如下图:
在这里插入图片描述

所以紧接着调用AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);

	private static class AopAutoProxyConfigurer {

		public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
				Object eleSource = parserContext.extractSource(element);
			  /*
			   * 创建一个AnnotationTransactionAttributeSource BeanDefinition,
			   * 它的作用类似于一个pointcut切入点,主要是判断方法或者类是否含有@Transactional注解
			   */
				RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

				// Create the TransactionInterceptor definition.
				/*
				 * 创建了一个TransactionInterceptor BeanDefinition,
				 * 它的作用主要是拦截器,拦截@Transactional注解,进行后续事务的一些处理			 
				 */
				RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
				interceptorDef.setSource(eleSource);
				interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				registerTransactionManager(element, interceptorDef);
				interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

				// Create the TransactionAttributeSourceAdvisor definition.
			  /*
				* 创建了一个BeanFactoryTransactionAttributeSourceAdvisor BeanDefinition
				* 它是一个真正的切面对象它包含了拦截器Interceptor(TransactionInterceptor)、
				* 切入点pointcut(AnnotationTransactionAttributeSource)
				* 提供给Spring AOP使用
				*/
				RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
				advisorDef.setSource(eleSource);
				advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
				if (element.hasAttribute("order")) {
					advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
				}
				parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

				CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
				compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
				parserContext.registerComponent(compositeDef);
			}
		}
	}

上面代码简单总结下就做了三件事

  1. 创建了一个切入点pointcut【AnnotationTransactionAttributeSource】,判断方法或者类是否含有@Transactional注解
  2. 创建了一个拦截器Interceptor【TransactionInterceptor】,主要进行拦截@Transactional注解后进行一些事务处理
  3. 创建了一个切面Aspect【BeanFactoryTransactionAttributeSourceAdvisor】,组装切入点和拦截器,提供给SpringAop生成代理使用

所以很显然,Spring对事务的操作是由TransactionInterceptor进行处理的

TransactionInterceptor源码分析

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

	public TransactionInterceptor() {
	}

	public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
		setTransactionManager(ptm);
		setTransactionAttributes(attributes);
	}

	public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
		setTransactionManager(ptm);
		setTransactionAttributeSource(tas);
	}


	@Override
	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, new InvocationCallback() {
			@Override
			public Object proceedWithInvocation() throws Throwable {
				return invocation.proceed();
			}
		});
	}
	....其他方法省略

}

这里直接调用了invokeWithinTransaction()方法。

org.springframework.transaction.interceptor.TransactionAspectSupport

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

		// If the transaction attribute is null, the method is non-transactional.
		/*
		 * 获取对应事务属性.如果事务属性为空(则目标方法不存在事务)
		 * 如果项目使用@Transactional注解,那么这里就对应Transactional注解的值
		 * 如果项目使用了,就是标签配置的属性的值
		 */		
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		// 根据事务的属性获取beanFactory中的PlatformTransactionManager(spring事务管理器的顶级接口),一般这里是DataSourceTransactiuonManager
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		
		// 如果事务属性为空 或者 tm 不是 编程式事务管理器
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {		
			// 判断是否需要创建一个事务,根据事务传播行为做出相应的处理
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// 执行下一个拦截器
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				// 异常回滚
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				// 清除事务信息
				cleanupTransactionInfo(txInfo);
			}
			// 提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			/**
			 * 下面是编程式事务处理,暂不做重点讨论
			 */
			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
						new TransactionCallback<Object>() {
							@Override
							public Object doInTransaction(TransactionStatus 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.
										return new ThrowableHolder(ex);
									}
								}
								finally {
									cleanupTransactionInfo(txInfo);
								}
							}
						});

				// Check result: It might indicate a Throwable to rethrow.
				if (result instanceof ThrowableHolder) {
					throw ((ThrowableHolder) result).getThrowable();
				}
				else {
					return result;
				}
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
		}
	}

重点分析createTransactionIfNecessary方法,它会判断是否存在事务,根据传播行为,做出相应的判断,主要是通过TransactionStatus对象进行包装

org.springframework.transaction.interceptor.TransactionAspectSupport

	protected TransactionInfo createTransactionIfNecessary(
			PlatformTransactionManager tm, 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);
	}

createTransactionIfNecessary方法实际上调用了getTransaction方法去判断是否具有事务,而且根据传播行为去做相应的处理

	public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
		// 这里主要是调用了PlatformTransactionManager的doGetTransaction方法去生成一个事务
		Object transaction = doGetTransaction();

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

		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'");
		}
		//如果是PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED这三种类型将开启一个新的事务
		else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
				definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			// 因为是全新的事务,所以不存在之前的事务,不需要挂起事务,所以调用suspend方法,传入null
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
			}
			try {
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				/*
				 * 创建一个TransactionStatus对象,后面介绍下这个对象的作用
				 */
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
				// 开启一个事务
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
			catch (RuntimeException ex) {
				resume(null, suspendedResources);
				throw ex;
			}
			catch (Error err) {
				resume(null, suspendedResources);
				throw err;
			}
		}
		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);
		}
	}

getTransaction的方法逻辑比较复杂一点,这里简单总结一下,后面在依次分析

  1. 调用PlatformTransactionManager的doGetTransaction方法,创建了一个Transaction事务对象,这个Transaction封装了数据库连接Connection对象。
  2. 调用isExistingTransaction(transaction)判断之前是否已经开启事务,如果已经开启事务了,那么调用handleExistingTransaction(definition, transaction, debugEnabled)进行相应的处理
  3. 如果没有开启事务,那么通过事务传播行为,然后在进行相应的处理。如果是PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED这三种类型将,并且调用doBegin方法开启一个新的事务

首先来看一下调用doGetTransaction方法,我们这里的事务管理器使用的是DataSourceTransactionManager

	protected Object doGetTransaction() {
		/*
		 * 创建一个DataSourceTransactionObject对象
		 * 这个对象主要用于存储数据库连接Connection对象,和一些Connection的状态标识
		 */
		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		/*
		 * TransactionSynchronizationManager对象有一个ThreadLocal变量,用于存储当前线程的ConnectionHolder,
		 * 并且该对象具有Connection的创建、删除等功能
		 * 这里实际上是从ThreadLocal取出一个ConnectionHolder
		 * (Tip:如果第一次进来,那么这里取出来肯定为空)
		 */
		ConnectionHolder conHolder =
				(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
		/*
		 * 把ConnectionHolder放入DataSourceTransactionObject对象中,
		 * 并且把传入false,标记该ConnectionHolder不是一个新的连接
		 */
		txObject.setConnectionHolder(conHolder, false);
		return txObject;
	}
	// key是dataSource,即数据源
	public static Object getResource(Object key) {
		Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
		// 把dataSource作为key,去ThreadLocal取出ConnectionHolder
		Object value = doGetResource(actualKey);
		if (value != null && logger.isTraceEnabled()) {
			logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread [" +
					Thread.currentThread().getName() + "]");
		}
		// 返回ConnectionHolder
		return value;
	}
	private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<Map<Object, Object>>("Transactional resources");
			
			
	private static Object doGetResource(Object actualKey) {
		// 从ThreadLocal取出一个Map
		Map<Object, Object> map = resources.get();
		// 如果该map为null,那么直接返回null
		if (map == null) {
			return null;
		}
		Object value = map.get(actualKey);
		// Transparently remove ResourceHolder that was marked as void...
		if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
			map.remove(actualKey);
			// Remove entire ThreadLocal if empty...
			if (map.isEmpty()) {
				resources.remove();
			}
			value = null;
		}
		return value;
	}

总结下TransactionSynchronizationManager.getResource()方法:Spring实际上是把Connection放入ThreadLocal中进行存储

紧接着我们回到isExistingTransaction(transaction)方法,去判断之前是否已经具有事务Transaction

	protected boolean isExistingTransaction(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		/*
		 * 这里判断ConnectionHolder是否为空 和 判断isTransaction是否为true
		 * 上面doGetTransaction方法说过,第一次进来ConnectionHolder为空,那么这里返回false
		 */		
		return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
	}

这里先看下如果之前没有开启事务,所以会执行doBegin方法,去开启新事务

	protected void doBegin(Object transaction, TransactionDefinition definition) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		Connection con = null;

		try {
			// 这里判断Transaction的ConnectionHolder为null
			if (txObject.getConnectionHolder() == null ||
					txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
				// 如果为null,那么从数据源DataSource去获取一个数据库连接Connection
				Connection newCon = this.dataSource.getConnection();
				if (logger.isDebugEnabled()) {
					logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
				}
				// 把新的ConnectionHolder连接放入Transaction对象,并且传入true,标记为全新的Connection
				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
			}
			
			// 从ConnectionHolder取出一个数据库连接
			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			con = txObject.getConnectionHolder().getConnection();

			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			txObject.setPreviousIsolationLevel(previousIsolationLevel);

			// 默认从数据源取出的连接Connection是自动提交
			if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				
				// 这里把Connection改为手动提交
				con.setAutoCommit(false);
			}

			prepareTransactionalConnection(con, definition);
			/*
			 * 把transaction标记为active,之前判断transaction是否存在的时候,就是通过这个标识
			 */
			txObject.getConnectionHolder().setTransactionActive(true);

			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

			// 如果是全新的Connection
			if (txObject.isNewConnectionHolder()) {
				// 把connection绑定到ThreadLocal上
				TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
			}
		}catch (Throwable ex) {
			if (txObject.isNewConnectionHolder()) {
				DataSourceUtils.releaseConnection(con, this.dataSource);
				txObject.setConnectionHolder(null, false);
			}
			throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
		}
	}

如果事务已经存在,那么调用handleExistingTransaction(definition, transaction, debugEnabled),根据传播行为,进行相应的处理

	private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {
		// 如果是PROPAGATION_NEVER
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			// 直接抛出异常
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}
		// 如果是PROPAGATION_NOT_SUPPORTED
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction");
			}
		// 把之前的Transaction直接挂起,返回一个SuspendedResourcesHolder,里面包装了挂起的数据库连接
			Object suspendedResources = suspend(transaction);
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			// 创建一个TransactionStatus,并且把当前Transaction置为null,并且包装了挂起的事务SuspendedResourcesHolder【用于后面恢复事务】,并且把newTransaction标记置为false
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}
		// 如果是TransactionDefinition.PROPAGATION_REQUIRES_NEW
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction, creating new transaction with name [" +
						definition.getName() + "]");
			}
		// 把之前的Transaction直接挂起,返回一个SuspendedResourcesHolder,里面包装了挂起的数据库连接
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			try {
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
			// 创建一个TransactionStatus,并且把当前Transaction置为null,并且包装了挂起的事务SuspendedResourcesHolder【用于后面恢复事务】,把newTransaction标记置为true
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
			  /*
			   * 之前已经讲过doBegin方法了,主要是把transaction绑定一个全新的数据库连接Connection
			   */
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
			catch (RuntimeException beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
			catch (Error beginErr) {
				resumeAfterBeginException(transaction, suspendedResources, beginErr);
				throw beginErr;
			}
		}
		// 如果是PROPAGATION_NESTED
		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()) {			
				// 如果之前已经开启了事务,那么就继续使用当前的事务,但是把是否为newTransaction的标记置为false
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
				// 并且创建一个savepoint
				status.createAndHoldSavepoint();
				return status;
			}
			else {
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				// 如果之前没有开启事务,那么就重新开启一个事务,跟PROPAGATION_REQUIRES很像
				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);
		// 如果是PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED,那么直接使用当前的Transaction,但是需要把newTransaction的标记置为false
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}

此时我们返回调用getTransaction方法的源点createTransactionIfNecessary

	protected TransactionInfo createTransactionIfNecessary(
			PlatformTransactionManager tm, 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);
	}

此时已经调用getTransaction,返回了一个TransactionStatus,这个对象主要包含了当前的Transaction、挂起的Transaction、并且还有一个很重要的标识newTransaction【这个标识表明当前的Transaction是否为全新的,后面在提交事务的时候有用】、还有一个savepoint。

紧接着调用prepareTransactionInfo方法

	protected TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm,
			TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {
		// 创建一个新的TransactionInfo
		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("Don't need to create transaction for [" + joinpointIdentification +
						"]: This method isn't transactional.");
		}
		
		// 把TransactionInfo绑定到线程上,也就是ThreadLocal
		txInfo.bindToThread();
		return txInfo;
	}

下面就是介绍事务的提交(comiit)、回滚(rollback)的操作

此时我们回到调用createTransactionIfNecessary方法的invokeWithinTransaction方法

	protected Object invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation)
			throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		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 {
			....省略
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
		}
	}

调用createTransactionIfNecessary后,返回了一个TransactionInfo对象,并且把这个对象绑定到在ThreadLocal,那么紧接着执行下一个拦截器

retVal = invocation.proceedWithInvocation();

当所有拦截器走完,并且调用了原始方法都没有出错,那么就会执行commitTransactionAfterReturning方法进行事务提交

	protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
		if (txInfo != null && txInfo.hasTransaction()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
			}
			// 调用事务管理器的commit方法,这里就是DataSourceTransactionManager
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}
	}
	
	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);
			return;
		}
		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
			}
			processRollback(defStatus);
			// Throw UnexpectedRollbackException only at outermost transaction boundary
			// or if explicitly asked to.
			if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
				throw new UnexpectedRollbackException(
						"Transaction rolled back because it has been marked as rollback-only");
			}
			return;
		}
		// 提交事务
		processCommit(defStatus);
	}
	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();
				}
				// 如果有savepoint
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Releasing transaction savepoint");
					}
					// 那么释放该savepoint
					status.releaseHeldSavepoint();
				}
				// 判断该Transaction是否为新的,即之前说的newTransaction标识
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction commit");
					}
					// 如果为全新的,那么执行doCommit进行提交
					doCommit(status);
				}
				// Throw UnexpectedRollbackException if we have a global rollback-only
				// marker but still didn't get a corresponding exception from commit.
				if (globalRollbackOnly) {
					throw new UnexpectedRollbackException(
							"Transaction silently rolled back because it has been marked as rollback-only");
				}
			}catch(){
			...省略一些无相关代码
			}
		finally {
			// 清除事务
			cleanupAfterCompletion(status);
		}
	}
	protected void doCommit(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		// 这里很熟悉,获取绑定在Transaction的数据库连接
		Connection con = txObject.getConnectionHolder().getConnection();
		if (status.isDebug()) {
			logger.debug("Committing JDBC transaction on Connection [" + con + "]");
		}
		try {
			// 调用Connection的commit方法进行提交
			con.commit();
		}
		catch (SQLException ex) {
			throw new TransactionSystemException("Could not commit JDBC transaction", ex);
		}
	}

cleanupAfterCompletion清除事务

	private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		// 把事务Transacion标记为完成
		status.setCompleted();
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.clear();
		}
		// 判断该Transaction是否为全新的
		if (status.isNewTransaction()) {
			// 如果Transaction是全新的,那么执行一些处理,比如说把connection释放回连接池、把connection.setAutoCommit(true)等等
			doCleanupAfterCompletion(status.getTransaction());
		}
		// 判断之前是否有挂起过别的Transaction事务
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction after completion of inner transaction");
			}
			// 如果有挂起过,那么需要进行恢复
			resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}
	protected final void resume(Object transaction, SuspendedResourcesHolder resourcesHolder)
			throws TransactionException {

		if (resourcesHolder != null) {
			// 获取上一个挂起的数据库连接Connection
			Object suspendedResources = resourcesHolder.suspendedResources;
			if (suspendedResources != null) {
				// 调用doResume,执行真正的恢复
				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(Object transaction, Object suspendedResources) {
	/*
	 * 这个方法很简单,直接把挂起的Connection连接,绑定到ThreadLocal,完成恢复
	 */
		TransactionSynchronizationManager.bindResource(this.dataSource, suspendedResources);
	}

回滚整个流程跟提交差不多,就不分析了。

你可能感兴趣的:(Spring4.x源码分析)