Spring源码学习(6)- 事务解析

Spring中事务,是使用AOP切面技术来实现的

事务的使用

使用事务时,要不就是在配置文件中配置,要不就是使用注解方式
使用注解方式的话,需要用到@EnableTransactionMangement注解,这个注解就显示的添加了注解事务功能,但是我们还需要定义数据源和事务管理平台

@EnableTransactionManagement
public class EnableTransactionManagementConfig{

	// 数据源的定义
	@Bean
	public DataSource comboPooledDataSource(){
		ComboPooledDataSource comboPooledDataSouce = new ComboPooledDataSource();
		/*
			中间一系列的操作
		*/
		return comboPooledDataSouce;
	}
	
	// 定义事务管理平台
	@Bean
	public PlatformTransactionManager annotationDrivenTransactionManager(DataSource dataSource){
		DataSourceTransactionManager manager = new DataSourceTransactionManager();
		manager.setDataSource(dataSource);
		return manager;
	}

}

@EnableTransactionMangement

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

}

跟Aop的注解一样。有个@Import注解,导入TransactionManagementConfigurationSelector 这个类

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
	// 如果没有设置AdviceMode,默认是AdviceMode.PROXY
	@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);
	}

}

@Import导入,是在refresh()过程中,invokeBeanFactoryPostProcessors() 这个方法去完成的
然后遍历执行实现了BeanDefinitionRegistryPostProcessor接口的子类d的postProcessBeanDefinitionRegistry()方法
在这里插入图片描述
主要的就是ConfigurationClassPostProcessor这个类,经过一系列操作后,会调用TransactionManagementConfigurationSelectorselectImports()方法,然后导入AutoProxyRegistrarProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration 这个类就是来加载数据源跟事务管理平台的

在jdbc中可得知事务是由connection对象控制的,所以connection对象和事务是绑定的
当用户请求过来时,需要数据库连接,来执行sql语句,所以用户请求跟数据库连接是绑定的

Spring事务传播属性

public enum Propagation {
	/*
		如果当前没有事务,就新建一个事务。
		如果已经存在一个事务中,加入到这个事务中
		默认事务
	*/ 
	REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
	/*
		支持当前事务,如果当前没有事务,就以非事务方式执行
	*/
	SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
	/*
		使用当前事务,如果没有事务,就抛异常
	*/
	MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
	/*
		新建事务,如果当前存在事务,就挂起当前事务
	*/
	REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
	/*
		以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
	*/
	NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),	
	/*
		以非事务方式执行,如果当前存在事务,则抛出异常
	*/
	NEVER(TransactionDefinition.PROPAGATION_NEVER),	
	/*
		如果当前存在事务,则在嵌套事务内执行。
		如果当前没有事务,则执行与REQUIRED类似的操作
	*/
	NESTED(TransactionDefinition.PROPAGATION_NESTED);

	private final int value;
	Propagation(int value) {this.value = value;}
	public int value() {return this.value;}

}

其中最常见的,就是PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_ESTED这三种。
事务的传播属性,是spring特有的,是spring用来控制方法事务的一种手段

传播属性的事务控制
使用@EnableTransactionManagement后,会导入TransactionManagementConfigurationSelector 这个类,然后在容器refresh的时候,会创建ProxyTransactionManagementConfiguration类。

ProxyTransactionManagementConfiguration 这个类,就是创建事务Advice跟事务切面实例的

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	/*
	* 明显是创建事务切面实例
	* BeanFactoryTransactionAttributeSourceAdvisor
	*
	* */
	@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();
	}

	/*
	* 创建事务advice
	* TransactionInterceptor
	* */
	@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;
	}

}

事务源码解析

TransactionInterceptor 这个类是事务企切面的Advice,所有有关spring的事务控制逻辑都在这个类里面,点进去看invoke方法,调用的是父类 TransactionAspectSupportinvokeWithinTransaction()发方法
可以将该方法分为几个部分
1.事务相关的处理
2.方法调用
3.提交或者回滚事务
4.释放资源和重新建立绑定关系

事务相关的处理

获取事务属性

// 获取事务属性类 AnnotationTransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();

// 获取方法上面有@Transactional注解的属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);	

创建事务对象

/*
	获取事务管理器
	1.先尝试从缓存中获取,有则直接返回缓存中的事务管理器
	2.如果缓存中不存在,则解析方法上@Transactional上的参数,并封装成RuleBasedTransactionAttribute对象返回
	3.放入缓存中
	
*/ 
final PlatformTransactionManager tm = determineTransactionManager(txAttr);

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) {
			// 开启事务
		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()
将该方法分成几个部分

1.获取DataSourceTransactionObject

// 获取DataSourceTransactionObject
Object transaction = doGetTransaction();

// -----------------------------------------
protected Object doGetTransaction() {
	// 管理connection对象,创建回滚点,按照回滚点回滚,释放回滚点
	DataSourceTransactionObject txObject = new DataSourceTransactionObject();

	// DataSourceTransactionManager默认是允许嵌套事务的
	txObject.setSavepointAllowed(isNestedTransactionAllowed());

	// obtainDataSource() 获取数据源对象,其实就是数据库连接块对象
	ConnectionHolder conHolder =
			(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
	txObject.setConnectionHolder(conHolder, false);
	return txObject;
}

2.判断当前是否有事务存在

// 判断当前是否有事务存在,如果有,进行一系列操作返回事务对象。第一次是不存在事务的
if (isExistingTransaction(transaction)) {
	// Existing transaction found -> check propagation behavior to find out how to behave.
	return handleExistingTransaction(definition, transaction, debugEnabled);
}

// --------------------------
protected boolean isExistingTransaction(Object transaction) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
	return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}

3.创建事务对象 DefaultTransactionStatus,这个类中有个属性很重要,就是newTransaction属性,
类型是boolean。

  • 如果为true,就代表当前事务允许单独提交和回滚,一般第一次创建事务,或者事务传播属性为PROPAGATION_REQUIRES_NEW的时候
  • 如果为false,则当前事务不能单独提交和回滚
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);

			// 开启事务,重点看看 DataSourceTransactionObject
			doBegin(transaction, definition);

			// 开启事务后,改变事务状态
			prepareSynchronization(status, definition);
			return status;
	}
	catch (RuntimeException | Error ex) {
		resume(null, suspendedResources);
		throw ex;
	}
}

4.开启事务doBegin()

  • 首先从数据源连接池中,获取数据库连接,并把连接封装成ConnectionHolder,设置到事务对象中
// 如果没有数据库连接
if (!txObject.hasConnectionHolder() ||
		txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
	// 从连接池里面获取连接
	Connection newCon = obtainDataSource().getConnection();
	if (logger.isDebugEnabled()) {
		logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
	}
	// 把连接包装成ConnectionHolder,然后设置到事务对象中
	txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
  • 关闭自动提交,这个就是开启了事务
con.setAutoCommit(false);
  • 建立当前线程与数据源的绑定关系(数据源与连接存入一个map中,)
// 如果是新创建的事务,则建立当前线程和数据库连接的关系
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());

事务就开启完毕了
当第二次进来的时候,又有事务的话,就会进入下面的逻辑

// 伪代码
class TransactionaDemoA{
	@Autowired
	TransactionaDemoB demoB;
	@Transactional
	void a(){	
		demoB.b();
	}
	
}
class TransactionaDemoB{
	
	@Transactional
	void b(){// ......}
}
// 这种情况下,会进入下面的代码

if (isExistingTransaction(transaction)) {
	// Existing transaction found -> check propagation behavior to find out how to behave.
	return handleExistingTransaction(definition, transaction, debugEnabled);
}
// -------------------------------
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);
		// 修改事务状态信息,把事务的一些信息存储到当前线程中,ThreadLocal中
		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);
}

重点看两种传播特性:
PROPAGATION_REQUIRES_NEW
如果没有事务,自己创建一个事务
如果有事务,挂起当前事务,并创建新的事务

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
	
	// 挂起
	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;
	}
}

// ------------------suspend()----------------
/*
	1.获取当前线程上一个数据库连接
	2.将事务的属性收集起来
	3.封装成SuspendedResourcesHolder对象
*/
if (transaction != null) {
	// 把connectionHolder设置为空,其实
	suspendedResources = doSuspend(transaction);
}

// 做数据还原操作
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);

// -----------------doSuspend()---------------------
/*
	该方法,就是根据数据源,去当前线程寻找对应的map,key为数据源,value为数据库连接
	1.先在ThreadLocal获取map。
	2.判断是否获取到,如果获取到,从map中删除并获取数据库连接
	3.从ThreadLocal中删除当前Map
	4.返回获取到的数据库连接
*/
protected Object doSuspend(Object transaction) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
	txObject.setConnectionHolder(null);
	//解除绑定关系
	return TransactionSynchronizationManager.unbindResource(obtainDataSource());
}

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

方法调用

aop的链式调用过程,如果不存在advice了,就会调用被代理方法,执行相应的业务操作




retVal = invocation.proceedWithInvocation();

提交或者回滚事务

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

事务回滚
可以看出,如果抛异常,不是一定回滚,会首先判断抛的异常,是否在回滚的返回中,如果不在还是会提交事务的

// catch部分被省略了
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
	try {
			txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
		}		
	}
	else {
		// We don't roll back on this exception.
		// Will still roll back if TransactionStatus.isRollbackOnly() is true.
		try {
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}
		
	}
}

事务提交

  • 如果有回滚点,清除回滚点,等其他事务提交
  • 如果newTransaction属性为true的话,就直接提交事务,如果不是的话,等其他事务提交
    newTransaction属性是在创建事务的时候,传入的
public final void commit(TransactionStatus status) throws TransactionException {
	// 省略其他代码
	processCommit(defStatus);
}

// -------------processCommit()--------------------

```java
if (status.hasSavepoint()) {
	if (status.isDebug()) {
		logger.debug("Releasing transaction savepoint");
	}
	unexpectedRollback = status.isGlobalRollbackOnly();
	status.releaseHeldSavepoint();
}
// 如果都是PROPAGATION_REQUIRED,最外层的才会走进来统一提交,如果是PROPAGATION_REQUIRES_NEW,每一个事务都会进来
else if (status.isNewTransaction()) {
	if (status.isDebug()) {
		logger.debug("Initiating transaction commit");
	}
	unexpectedRollback = status.isGlobalRollbackOnly();
	doCommit(status);
}

释放资源和重新建立绑定关系

AbstractPlatformTransactionManager.processCommit()方法中,在事务提交之后的finally语句块里

  • 首先,判断当前事务的newTransaction 是否为true,如果为true,才可以释放连接资源
  • 然后,判断当前事务有没有挂起的连接,如果有,恢复挂起的连接

恢复挂起的连接就是重新建立当前线程和连接对象的绑定关系

finally {
	cleanupAfterCompletion(status);
}

// ---------------------------------
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
	status.setCompleted();
	if (status.isNewSynchronization()) {
		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);
		// 恢复挂起连接的绑定
		resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值