spring source code series---transaction

@EnableTransactionManagement declarative things,

There is no need to write this note in SpringBoot, because the startup configuration spring-boot-autoconfigure-2.2.13.RELEASE.jar has been turned
on, and the automatic configuration class EnableAutoConfiguration=\ is configured in the spring.factories file under META-INF TransactionAutoConfiguration

TransactionAutoConfiguration	两个注解类:		PlatformTransactionManager、HibernateJpaAutoConfiguration、DataSourceTransactionManagerAutoConfiguration	两个内部类:		TransactionTemplateConfiguration 事物模板配置类		EnableTransactionManagementConfiguration 开启事物管理器配置类,支持两种方式			CglibAutoProxyConfiguration 默认没有配置走他,说明注解在类上			JdkDynamicAutoProxyConfiguration			这两个方法上都由@EnableTransactionManagement,@@以上就是自动装配			@EnableTransactionManagement	事物通知方式AdviceMode:PROXY(默认)、ASPECTJ		@Import({TransactionManagementConfigurationSelector.class})		AutoProxyRegistrar			AopConfigUtils.registerAutoProxyCreatorIfNecessary				AopConfigUtils#registerAutoProxyCreatorIfNecessary					注册InfrastructureAdvisorAutoProxyCreator,父类中继承了InstantiationAwareBeanPostProcessor因此会在bean的生命周期回调,作用就是开启自动代理		ProxyTransactionManagementConfiguration 			BeanFactoryTransactionAttributeSourceAdvisor 表示PointcutAdvisor			TransactionAttributeSource 表示Pointcut				AnnotationTransactionAttributeSource 在匹配时会检查类或者方法上是否有@Transaction注解			TransactionInterceptor 代理逻辑Advice这里作用就是向spring容器中添加一个Advisor,有了Advisor,那么spring构造bean时就会查看当前bean是不是匹配所设置的Pointcut(也就是类或者方法上是否有@Transaction注解)。如果匹配则利用所设置的Adivice(TransactionInterceptor)进行AOP生产代理对象,@@以上通过spring后置处理器来触发完成

The following is the aop initialization logic, here is the same, the difference is that the callBack set here is TransactionInterceptor

AbstractAutowireCapableBeanFactory#doCreateBean 跟AOP一样bean的后置处理器,在bean实例化后会进行回调	initializeBean		applyBeanPostProcessorsAfterInitialization			AbstractAutoProxyCreator#postProcessAfterInitialization 执行后置处理器				AbstractAutoProxyCreator#wrapIfNecessary					getAdvicesAndAdvisorsForBean 获取需要被代理的类						AbstractAutoProxyCreator#createProxy 配置ProxyFactory							ProxyFactory#getProxy 选择jdk动态代理还是Cglib								CglibAopProxy#getProxy 这里以Cglib为例									Enhancer 构建Enhancer										设置Callback为 DynamicAdvisedInterceptor,它实现了MethodInterceptor;代理类会经过并执行intercept方法

If you don’t understand the previous content, you can read the article on aop.

org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration

public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration { 	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) { 		// PointcutAdvisor		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();		// Pointcut		advisor.setTransactionAttributeSource(transactionAttributeSource);		// Advice		advisor.setAdvice(transactionInterceptor); 		if (this.enableTx != null) {			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));		}		return advisor;	} 	@Bean	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)	public TransactionAttributeSource transactionAttributeSource() {		return new AnnotationTransactionAttributeSource();	} 	@Bean	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)	public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {		TransactionInterceptor interceptor = new TransactionInterceptor();		interceptor.setTransactionAttributeSource(transactionAttributeSource);		if (this.txManager != null) {			interceptor.setTransactionManager(this.txManager);		}		return interceptor;	} }

org.springframework.transaction.interceptor.TransactionInterceptor#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);	}

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

Here is the parent class

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,			final InvocationCallback invocation) throws Throwable { 		// 如果transaction属性为null,则该方法为非事务处理。		// If the transaction attribute is null, the method is non-transactional.		TransactionAttributeSource tas = getTransactionAttributeSource(); 		// 获取正在执行方法上的@Transaction注解信息		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null); 		// 获取正在执行方法上是否指定TransactionManager,没有则生成默认的TransactionManager		final TransactionManager tm = determineTransactionManager(txAttr); 		// 下面情况暂时不考虑		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		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) {				// 执行业务方法出错,这里会先执行finally中的方法然后在抛出异常				// target invocation exception				completeTransactionAfterThrowing(txInfo, ex);				throw ex;			}			finally {				// 如果没有出错也是先执行这里然后再进行提交				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;		}	}

1, getTransactionAttributeSource to obtain annotation information

2. asPlatformTransactionManager obtains TransactionManager, which must be PlatformTransactionManager

3. MethodIdentification generates joinpointIdentification as the name of the thing

org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary starts to create a transaction and constructs TransactionInfo transaction object information

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) {				// 创建TransactionStatus对象子流程,并开启事务				status = tm.getTransaction(txAttr);			}			else {				if (logger.isDebugEnabled()) {					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +							"] because no transaction manager has been configured");				}			}		} 		// 封装一个TransactionInfo对象		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);	}

org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)			throws TransactionException { 		// 如果未提供事务定义,请使用默认值		// Use defaults if no transaction definition given.		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults()); 		// 创建事务对象,这里得到的事务对象中可能没有数据库链接		// org.springframework.jdbc.datasource.DataSourceTransactionManager.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 {				// 构造一个TransactionStatus对象				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);		}	}
判断是否持有数据库连接	YES		判断传播机制	NO		判断传播机制startTransaction 开始事物	doBegin		DataSourceTransactionManager#doBegin			设置数据库事物对象			设置数据库隔离级别			设置AutoCommit=false			设置数据库连接超时时间			prepareSynchronization 设置TransactionSynchronizationManager

org.springframework.transaction.support.AbstractPlatformTransactionManager#startTransaction

private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,			boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) { 		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); 		DefaultTransactionStatus status = newTransactionStatus(				definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); 		// todo		doBegin(transaction, definition); 		prepareSynchronization(status, definition);		return status;	}

org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin

protected void doBegin(Object transaction, TransactionDefinition definition) {		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;		Connection con = null; 		try {			if (!txObject.hasConnectionHolder() ||					txObject.getConnectionHolder().isSynchronizedWithTransaction()) { 				// 获取数据库连接并设置到				Connection newCon = obtainDataSource().getConnection();				if (logger.isDebugEnabled()) {					logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");				}				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);			} 			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);			con = txObject.getConnectionHolder().getConnection(); 			// 设置隔离级别			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);			txObject.setPreviousIsolationLevel(previousIsolationLevel);			txObject.setReadOnly(definition.isReadOnly()); 			// 设置数据库连接的AutoCommit为false			// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,			// so we don't want to do it unnecessarily (for example if we've explicitly			// configured the connection pool to set it already).			if (con.getAutoCommit()) {				txObject.setMustRestoreAutoCommit(true);				if (logger.isDebugEnabled()) {					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");				}				// 关闭自动提交				con.setAutoCommit(false);			} 			prepareTransactionalConnection(con, definition);			txObject.getConnectionHolder().setTransactionActive(true); 			// 设置数据库超时时间			int timeout = determineTimeout(definition);			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);			} 			// 把获得的数据库连接对象通过TransactionSynchronizationManager设置到当前线程的ThreadLocal中			// Bind the connection holder to the thread.			if (txObject.isNewConnectionHolder()) {				// 绑定到ThreadLocal中,key为数据库对象,value为连接信息				TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());			}		} 		catch (Throwable ex) {			if (txObject.isNewConnectionHolder()) {				DataSourceUtils.releaseConnection(con, obtainDataSource());				txObject.setConnectionHolder(null, false);			}			throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);		}	}

org.springframework.jdbc.datasource.DataSourceTransactionManager#doGetTransaction Get transaction object

protected Object doGetTransaction() { 		// 如果本次开始事务的当前线程是第一次开启事务,那么获得的事务对象中就没有数据链接		// 反之如果本次开启事务的线程中还有事务没提交,那么获得的事务对象中就有数据库链接		DataSourceTransactionObject txObject = new DataSourceTransactionObject(); 		// 设置保存点		txObject.setSavepointAllowed(isNestedTransactionAllowed()); 		// 获取数据库链接		ConnectionHolder conHolder =				(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());		txObject.setConnectionHolder(conHolder, false);		return txObject;	}

org.springframework.transaction.interceptor.TransactionAspectSupport#prepareTransactionInfo

protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,			@Nullable TransactionAttribute txAttr, String joinpointIdentification,			@Nullable TransactionStatus status) { 		TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);		if (txAttr != null) {			// We need a transaction for this method...			if (logger.isTraceEnabled()) {				logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");			}			// The transaction manager will flag an error if an incompatible tx already exists.			txInfo.newTransactionStatus(status);		}		else {			// The TransactionInfo.hasTransaction() method will return false. We created it only			// to preserve the integrity of the ThreadLocal stack maintained in this class.			if (logger.isTraceEnabled()) {				logger.trace("No need to create transaction for [" + joinpointIdentification +						"]: This method is not transactional.");			}		}         // 数据库连接对象绑定到当前线程的ThreadLocal		// We always bind the TransactionInfo to the thread, even if we didn't create		// a new transaction here. This guarantees that the TransactionInfo stack		// will be managed correctly even if no transaction was created by this aspect.		txInfo.bindToThread();		return txInfo;	}

org.springframework.transaction.interceptor.TransactionAspectSupport.TransactionInfo#bindToThread

private void bindToThread() {			// Expose current TransactionStatus, preserving any existing TransactionStatus			// for restoration after this transaction is complete.			this.oldTransactionInfo = transactionInfoHolder.get();			transactionInfoHolder.set(this);		}

proceedWithInvocation execute business method

org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing Error executing business method

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {		if (txInfo != null && txInfo.getTransactionStatus() != null) {			if (logger.isTraceEnabled()) {				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +						"] after exception: " + ex);			}			// 默认只有RuntimeException和Error才会执行回滚,否则还会继续提交			if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {				try {					txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());				}				catch (TransactionSystemException ex2) {					logger.error("Application exception overridden by rollback exception", ex);					ex2.initApplicationException(ex);					throw ex2;				}				catch (RuntimeException | Error ex2) {					logger.error("Application exception overridden by rollback exception", ex);					throw ex2;				}			}			else {				// We don't roll back on this exception.				// Will still roll back if TransactionStatus.isRollbackOnly() is true.				try {					// 继续提交					txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());				}				catch (TransactionSystemException ex2) {					logger.error("Application exception overridden by commit exception", ex);					ex2.initApplicationException(ex);					throw ex2;				}				catch (RuntimeException | Error ex2) {					logger.error("Application exception overridden by commit exception", ex);					throw ex2;				}			}		}	}

org.springframework.transaction.support.AbstractPlatformTransactionManager#rollback needs to be rolled back

public final void rollback(TransactionStatus status) throws TransactionException { 		// 如果已经执行完成则抛出异常		if (status.isCompleted()) {			throw new IllegalTransactionStateException(					"Transaction is already completed - do not call commit or rollback more than once per transaction");		} 		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; 		// 回滚处理		processRollback(defStatus, false);	}

org.springframework.transaction.support.AbstractPlatformTransactionManager#processRollback

private void processRollback(DefaultTransactionStatus status, boolean unexpected) {		try {			boolean unexpectedRollback = unexpected; 			try {				// 触发同步器的BeforeCompletion				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");					}					// 调用数据库连接对象的Rollback					doRollback(status);				}				else {					// Participating in larger transaction					if (status.hasTransaction()) {						if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {							if (status.isDebug()) {								logger.debug("Participating transaction failed - marking existing transaction as rollback-only");							}							doSetRollbackOnly(status);						}						else {							if (status.isDebug()) {								logger.debug("Participating transaction failed - letting transaction originator decide on rollback");							}						}					}					else {						logger.debug("Should roll back transaction but cannot - no transaction available");					}					// 如果设置了全局的快速失败					// Unexpected rollback only matters here if we're asked to fail early					if (!isFailEarlyOnGlobalRollbackOnly()) {						unexpectedRollback = false;					}				}			}			catch (RuntimeException | Error ex) {				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);				throw ex;			} 			// 触发同步器的AfterCompletion			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); 			// Raise UnexpectedRollbackException if we had a global rollback-only marker			if (unexpectedRollback) {				throw new UnexpectedRollbackException(						"Transaction rolled back because it has been marked as rollback-only");			}		}		finally {			cleanupAfterCompletion(status);		}	}

org.springframework.transaction.support.AbstractPlatformTransactionManager#cleanupAfterCompletion Check if any transaction is pending

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

org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning Submit the sub-process without exception

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

org.springframework.transaction.support.AbstractPlatformTransactionManager#commit

public final void commit(TransactionStatus status) throws TransactionException {		if (status.isCompleted()) {			throw new IllegalTransactionStateException(					"Transaction is already completed - do not call commit or rollback more than once per transaction");		} 		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;		if (defStatus.isLocalRollbackOnly()) {			if (defStatus.isDebug()) {				logger.debug("Transactional code has requested rollback");			}			processRollback(defStatus, false);			return;		} 		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {			if (defStatus.isDebug()) {				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");			}			processRollback(defStatus, true);			return;		} 		processCommit(defStatus);	}

org.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit

private void processCommit(DefaultTransactionStatus status) throws TransactionException {		try {			boolean beforeCompletionInvoked = false; 			try {				boolean unexpectedRollback = false; 				prepareForCommit(status); 				// 触发同步器的BeforeCommit				triggerBeforeCommit(status); 				// 触发同步器的BeforeCompletion				triggerBeforeCompletion(status); 				beforeCompletionInvoked = true; 				if (status.hasSavepoint()) {					if (status.isDebug()) {						logger.debug("Releasing transaction savepoint");					}					unexpectedRollback = status.isGlobalRollbackOnly();					status.releaseHeldSavepoint();				}				else if (status.isNewTransaction()) {					if (status.isDebug()) {						logger.debug("Initiating transaction commit");					}					unexpectedRollback = status.isGlobalRollbackOnly(); 					// 调用数据库连接的Commit					doCommit(status);				}				else if (isFailEarlyOnGlobalRollbackOnly()) {					unexpectedRollback = status.isGlobalRollbackOnly();				} 				// Throw UnexpectedRollbackException if we have a global rollback-only				// marker but still didn't get a corresponding exception from commit.				if (unexpectedRollback) {					throw new UnexpectedRollbackException(							"Transaction silently rolled back because it has been marked as rollback-only");				}			}			catch (UnexpectedRollbackException ex) {				// can only be caused by doCommit				triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);				throw ex;			}			catch (TransactionException ex) {				// can only be caused by doCommit				if (isRollbackOnCommitFailure()) {					doRollbackOnCommitException(status, ex);				}				else {					triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);				}				throw ex;			}			catch (RuntimeException | Error ex) {				if (!beforeCompletionInvoked) {					triggerBeforeCompletion(status);				}				doRollbackOnCommitException(status, ex);				throw ex;			} 			// Trigger afterCommit callbacks, with an exception thrown there			// propagated to callers but the transaction still considered as committed.			try {				// 触发同步器的AfterCommit				triggerAfterCommit(status);			}			finally {				// 触发同步器的AfterCompletion				triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);			} 		}		finally {			cleanupAfterCompletion(status);		}	}

Post an analysis step

TransactionInterceptor#invoke	TransactionAspectSupport#invokeWithinTransaction 这里调用的是父类		getTransactionAttribute 获取注解信息			asPlatformTransactionManager 获取TransactionManager,必须是PlatformTransactionManager			methodIdentification 生成joinpointIdentification作为事物的名字			createTransactionIfNecessary 开始创建事物				TransactionAspectSupport#createTransactionIfNecessary 构建TransactionInfo事物对象信息					getTransaction 						AbstractPlatformTransactionManager#getTransaction							doGetTransaction								DataSourceTransactionManager#doGetTransaction 得到事物对象									判断是否持有数据库连接										YES											判断传播机制										NO											判断传播机制									startTransaction 开始事物										doBegin											DataSourceTransactionManager#doBegin												设置数据库事物对象												设置数据库隔离级别												设置AutoCommit=false												设置数据库连接超时时间												prepareSynchronization 设置TransactionSynchronizationManager				prepareTransactionInfo						TransactionAspectSupport.TransactionInfo#bindToThread 把数据库连接对象绑定到当前线程的ThreadLocal			proceedWithInvocation 执行业务方法			有异常				回滚事物子流程					需要回滚 - 触发同步器的beforeCompletion - 调用数据库连接对象的rollback - 触发同步器的afterCompletion - 判断是否有事物挂起 - 如果有就把挂起的事物重新设置到TransactionSynchronizationManager,并执行同步器的resume方法			无异常				提交子流程 - 触发同步器的beforeCommit - 触发同步器的beforeCompletion - 调用数据库连接对象的commit - 触发同步器的afterCommit - 触发同步器的afterCompletion - 判断是否有事物挂起 - 如果有就把挂起的事物重新设置到TransactionSynchronizationManager,并执行同步器的resume方法

1. Get the annotation information, get the TransactionManager, and generate the name of the transaction

2. Begin to create a transaction, first determine the database connection and propagation mechanism, and then start the transaction, then set the database transaction object, database isolation level, turn off auto-commit, and prepare the transaction management synchronizer.

3. Execute business methods

4. If there is an exception, the transaction sub-process is rolled back, and at the same time, whether there is a transaction pending, etc., the transaction sub-process is submitted without exception.

Simple process:

1. Generate transaction state objects

2. Transaction doBegin, obtain and set the database connection to the transaction state object

3. Set the transaction information to the transaction synchronization manager

4. Execute business logic method

4.1 Generate a transaction state object, and you can get the database connection that already exists in the current thread

4.2 Determine that there is a transaction in the current thread

4.3 If you need to start a new transaction, first suspend the current database connection. Suspension is to transfer the test transaction information from the transaction synchronization manager to the suspended resource object, and set the database connection in the current a transaction state object to null

4.4 a transaction doBegin, a new database connection is generated and set to a transaction state object

4.5 Set a transaction information to the transaction synchronization manager

4.6 Execute a business logic method

4.7 Use a transaction state object to perform commit

4.8 The suspended transaction will be resumed after submission. The recovery here is actually just transferring the information stored in the suspended resource object back to the transaction synchronization manager

5. Continue to execute the business logic method

6. Use the transaction state object to perform the commit