Spring 随笔 transactional 3-事务创建(之前没有事务,则创建并启动事务)

1. 从配置类开局注入的 TransactionInterceptor 入手

	// public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor
	// org.springframework.transaction.interceptor.TransactionInterceptor#invoke
	@Override
	@Nullable
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// 获取被代理的类
		// 因为TransactionAttribute是间接的跟targetClass绑定的
		// 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);

		// step into ...
		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}
	
	// org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// 直接返回,即return this.transactionAttributeSource;
		// 基于注解(声明式事务)的属性源是AnnotationTransactionAttributeSource
		// If the transaction attribute is null, the method is non-transactional.
		TransactionAttributeSource tas = getTransactionAttributeSource();
		
		// 根据TransactionAttributeSource获取对应方法(需要有事务的话)的事务参数TransactionAttribute
		// 其实就是AOP之前解析@Transactional注解获取事务参数的那个过程
		// 因此,这里我们就不再 step into 了
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		
		// step into ...
		// 确定使用的事务管理器TransactionManager
		final TransactionManager tm = determineTransactionManager(txAttr);

		// 这里用于spring5的响应式编程,略过吧
		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			// ...
			return txSupport.invokeWithinTransaction(
					method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
		}

		// 强转事务管理器的类型
		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		
		// step into ...
		// 获取需要纳入事务的方法的joinpoint连接点相关的信息,主要用作记录日志
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

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

			Object retVal;
			try {
			
				// 其实就是调用方法入参中的回调函数,说白了就是aop过程中的MethodInvocation.proceed()
				// 就像是一个环绕通知,在这里做了对下一个拦截器的调用罢了
				// 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);
			}

			// 略过吧...
			//类路径上存在Vavr库时的处理,这个需要引入外部依赖,因此一般都是不存在的
			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 {
			// 先略过吧,这一块目前不太接触得到
			// 如果txAttr不为null并且事务管理器属于CallbackPreferringPlatformTransactionManager,走下面的逻辑
		}
	}

2. determineTransactionManager:确立并返回对应的事务管理器

	// org.springframework.transaction.interceptor.TransactionAspectSupport#determineTransactionManager
	@Nullable
	protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
		// Do not attempt to lookup tx manager if no tx attributes are set
		if (txAttr == null || this.beanFactory == null) {
			return getTransactionManager();
		}

		// 根据@Transactional中的value属性指定了事务管理器
		String qualifier = txAttr.getQualifier();
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(this.beanFactory, qualifier);
		}
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
		}
		else {
			// 这里就是return this.txmanager,此时还是null
			// 默认set的事务管理器是个Null
			TransactionManager defaultTransactionManager = getTransactionManager();
			if (defaultTransactionManager == null) {
			
				// 尝试命中事务管理器的缓存
				// 缓存第一次访问也是null
				defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
				if (defaultTransactionManager == null) {
				
					// 在ioc容器中找到TransactionManager类型的bean注入
					// 这里我们获取到的是DateSourceTransactionManager
					defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
					// 缓存起来
					this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			
			// end ...
			return defaultTransactionManager;
		}
	}

3. methodIdentification:获取连接点的标识符

	// org.springframework.transaction.interceptor.TransactionAspectSupport#methodIdentification(java.lang.reflect.Method, java.lang.Class<?>, org.springframework.transaction.interceptor.TransactionAttribute)
	private String methodIdentification(Method method, @Nullable Class<?> targetClass,
			@Nullable TransactionAttribute txAttr) {

		String methodIdentification = methodIdentification(method, targetClass);
		if (methodIdentification == null) {
			if (txAttr instanceof DefaultTransactionAttribute) {
				// 这里值即我们前面解析@Transactional得到TransactionAttribute的时候赋值的
				methodIdentification = ((DefaultTransactionAttribute) txAttr).getDescriptor();
			}
			if (methodIdentification == null) {
				methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
			}
		}
		
		// end ...
		// 诸如这样子的方法签名而已
		// com.weng.cloud.sample.tx.TxHandler.t
		return methodIdentification;
	}

4. createTransactionIfNecessary:创建事务的封装实例TransactionInfo

	// org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
	protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

		// 如果TransactionAttribute为null,则创建一个并且以方法的被代理的全限定名作为连接点标识
		// 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) {
			
				// step into ...
				// 获取到一个TransactionStatus
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
		// step into ...
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}

4.1 getTransaction:从事务管理器中获取一个TransactionStatus

	// org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
	@Override
	public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException {

		// 如果TransactionAttribute为null,则创建一个默认的
		// Use defaults if no transaction definition given.
		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

		// step into ...
		// 获取当前事务,该方法由具体的事务管理器子类自己实现,比如DataSourceTransactionManager、JtaTransactionManager
		// 对于DataSourceTransactionManager这里获取的实际上是一个数据库的事务连接对象,即DataSourceTransactionObject
		Object transaction = doGetTransaction();
		boolean debugEnabled = logger.isDebugEnabled();

		// step into ...
		// 是否开启事务	
		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());
		}

		// 当事务传播行为是PROPAGATION_MANDATORY(如果存在事务,抛出异常)
		// 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) {
			
			// step into ...
			//暂停给定的事务。首先挂起事务同步,然后再委派给doSuspend模板方法。
			//由于此前没有事务,所以参数事务为null
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
			}
			try {
			
				// step into ...
				//开启一个新事务并返回
				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);
			}
			// step into ...
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			// step into ...
			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
		}
	}

4.1.1 doGetTransaction:返回一个TransactionObject(ConnectHolder的事务封装)

	// org.springframework.jdbc.datasource.DataSourceTransactionManager#doGetTransaction
	@Override
	protected Object doGetTransaction() {
		//创建一个DataSourceTransactionObject,由DataSourceTransactionManager用作内部事务对象。
		//内部可能会持有一个ConnectionHolder对象,还具有创建、回滚、释放保存点的功能
		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
		//设置是否允许保存点,DataSourceTransactionManager默认会允许,用于实现嵌套事务
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		// step into ...
		ConnectionHolder conHolder =
				(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
		txObject.setConnectionHolder(conHolder, false);
		return txObject;
	}

	// org.springframework.transaction.support.TransactionSynchronizationManager#getResource
	@Nullable
	public static Object getResource(Object key) {
		// 如有必要,解开给定的资源句柄,否则按原样返回给定的句柄,用常用于从各种代理对象中获取原始对象
		// key:dataSource对象
		Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
		// step into ...
		// 将返回DataSource对象对应的ConnectHolder
		Object value = doGetResource(actualKey);
		if (value != null && logger.isTraceEnabled()) {
			logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread [" +
					Thread.currentThread().getName() + "]");
		}
		return value;
	}
	
	// org.springframework.transaction.support.TransactionSynchronizationManager#doGetResource
	@Nullable
	private static Object doGetResource(Object actualKey) {
		// private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<>("Transactional resources");
		// TransactionSynchronizationManager众多ThreadLocal中的一个
		// bindResource()用于绑定ConnectHolder,即map.put
		// 顺带一提:事务开启时doBegin()会有这个动作
		Map<Object, Object> map = resources.get();
		if (map == null) {
			return null;
		}
		// 缓存嘛
		Object value = map.get(actualKey);
		// 删除无效的ResourceHolder(这里来说,即ConnectHolder)
		// 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;
		}
		// end ...
		return value;
	}

4.1.2 isExistingTransaction:当前事务的ConnectHolder中是否存在过的事务

	//org.springframework.jdbc.datasource.DataSourceTransactionManager#isExistingTransaction
	@Override
	protected boolean isExistingTransaction(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		// step out ...
		// DataSourceTransactionManager的方法将会判断上面获取的DataSourceTransactionObject内部的数据库连接connectionHolder属性是否不为null,
		// 并且是否已经开启了事务。我们说过如果当前线程是第一次进来,那么connectionHolder就是null。
		return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
	}

4.1.3 suspend:挂起事务

	// org.springframework.transaction.support.AbstractPlatformTransactionManager#suspend
	@Nullable
	protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
		//如果当前线程的事务同步处于活动状态,即存在绑定的TransactionSynchronization,则返回true。
		//如果是第一次因为进来,那么自然为false
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
			try {
				Object suspendedResources = null;
				if (transaction != null) {
				
					// step into ...
					// 挂起事务,由具体的子类实现
					suspendedResources = doSuspend(transaction);
				}
				// 获取当前事务的信息,并且清空各个ThreadLocal缓存中的当前线程的当前事务信息(恢复为默认值)
				String name = TransactionSynchronizationManager.getCurrentTransactionName();
				TransactionSynchronizationManager.setCurrentTransactionName(null);
				boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
				TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
				Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
				boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
				TransactionSynchronizationManager.setActualTransactionActive(false);
				
				// 将获取的当前事物的信息存入一个SuspendedResourcesHolder对象中返回
				return new SuspendedResourcesHolder(
						suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
			}
			catch (RuntimeException | Error ex) {
				// doSuspend failed - original transaction is still active...
				doResumeSynchronization(suspendedSynchronizations);
				throw ex;
			}
		}
		
		// 如果没有事务同步但是开启了事务,那么挂起之前的事务
		else if (transaction != null) {
			// step into ...
			// Transaction active but no synchronization active.
			Object suspendedResources = doSuspend(transaction);
			return new SuspendedResourcesHolder(suspendedResources);
		}
		else {
			// step out ...
			// 当前不存在其他的事务
			// Neither transaction nor synchronization active.
			return null;
		}
	}

	// org.springframework.jdbc.datasource.DataSourceTransactionManager#doSuspend
	@Override
	protected Object doSuspend(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		txObject.setConnectionHolder(null);
		// 解绑当前线程中dataSource对应的resourceHolder(ConnectHolder)
		return TransactionSynchronizationManager.unbindResource(obtainDataSource());
	}

4.1.4 startTransaction:开启事务

// org.springframework.transaction.support.AbstractPlatformTransactionManager#startTransaction
	private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
			boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

		//判断是否需要开启新同步,默认都是SYNCHRONIZATION_ALWAYS,即需要开启
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
				
		// step into ...
		// 真正的开启事务
		// 这里将计算得到真正的超时参数
		doBegin(transaction, definition);
		
		// step into ...
		// 准备事务同步
		prepareSynchronization(status, definition);
		return status;
	}
4.1.4.1 DataSourceTransactionManager.doBegin:事务开启的底层执行逻辑
	// org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin
	@Override
	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);
			}

			// 获取事务对象的连接持有者,将synchronizedWithTransaction设置为true,即资源标记为与事务同步。
			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			con = txObject.getConnectionHolder().getConnection();

			// 赋值配置的事务隔离级别
			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			txObject.setPreviousIsolationLevel(previousIsolationLevel);
			txObject.setReadOnly(definition.isReadOnly());

			// 是否设置自动提交事务
			// 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");
				}
				
				/*
				 * 如果上面判断是自动提交,那么切换为手动提交,为什么呢?如果不手动提交,
				 * 那么一个方法中执行多个sql语句时将会每执行一个提交一次,无法实现事务的控制
				 * 开启手动提交就能实现方法级别的整体事务控制
				 *
				 * 并且,开启手动提交时,将会自动开启事物
				 */
				con.setAutoCommit(false);
			}

			/*
			 *
			 * 事务开始后立即准备事务连接,主要是对于只读事务的优化操作(需要手动开启)
			 * 如果将"enforceReadOnly"标志设置为true(默认为false),并且事务定义指示只读事务,
			 * 则默认实现将执行"SET TRANSACTION READ ONLY"这一个sql语句。

			 * 请注意mysql只读事务不要开启,oracle的只读事务可以开启
			 */
			prepareTransactionalConnection(con, definition);
			
			// 设置事务ConnectionHolder的transactionActive属性为true,表示激活当前连接的事务
			// 此前判断是否有开启事务的isExistingTransaction方法就会判断这个属性
			txObject.getConnectionHolder().setTransactionActive(true);

			// 设置事务超时时间
			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				// step into ...
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

			// 如果是新的连接持有者,即newConnectionHolder属性为true
			// Bind the connection holder to the thread.
			if (txObject.isNewConnectionHolder()) {
				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);
		}
	}
4.1.4.1.1 setTimeoutInSeconds:事务超时配置传递到事务资源上
	// org.springframework.transaction.support.ResourceHolderSupport#setTimeoutInSeconds
	public void setTimeoutInSeconds(int seconds) {
		// step into ...
		// s -> ms
		setTimeoutInMillis(seconds * 1000L);
	}
	
	// org.springframework.transaction.support.ResourceHolderSupport#setTimeoutInMillis
	public void setTimeoutInMillis(long millis) {
		// 因为事务创建、开启是在第一个SQL代码的调用时候
		// 因此可以知道SQL执行前延时将影响到超时,放SQL调用后不会有任何影响
		// step out ...
		this.deadline = new Date(System.currentTimeMillis() + millis);
	}
4.1.4.2 prepareSynchronization:事务资源同步到当前线程
	// org.springframework.transaction.support.AbstractPlatformTransactionManager#prepareSynchronization
	protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
		// 是否顶层事务
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
			
			// 如果隔离级别是默认,则设置null,否则设置对应的隔离级别
			TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
					definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
							definition.getIsolationLevel() : null);
			TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
			TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
		
			// step into ...
			TransactionSynchronizationManager.initSynchronization();
		}
	}
	
	// org.springframework.transaction.support.TransactionSynchronizationManager#initSynchronization
	public static void initSynchronization() throws IllegalStateException {
		if (isSynchronizationActive()) {
			throw new IllegalStateException("Cannot activate transaction synchronization - already active");
		}
		logger.trace("Initializing transaction synchronization");
		
		// 重新初始化存放当前线程活跃的threadlocal
		synchronizations.set(new LinkedHashSet<>());
	}

4.1.5 getTransactionSynchronization:默认时刻保持事务资源与线程同步

	// 始终激活事务同步
	public static final int SYNCHRONIZATION_ALWAYS = 0;
	private int transactionSynchronization = SYNCHRONIZATION_ALWAYS;
	// org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransactionSynchronization
	public final int getTransactionSynchronization() {
		return this.transactionSynchronization;
	}

4.1.6 prepareTransactionStatus:初始化其内部的TransactionSynchronization

  • prepareTransactionStatus:其实就是没有doBegin()的startTransaction()
	// org.springframework.transaction.support.AbstractPlatformTransactionManager#prepareTransactionStatus
	protected final DefaultTransactionStatus prepareTransactionStatus(
			TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
			boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {

		// 就是 new DefaultTransactionStatus
		DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
				
		// step into ...
		prepareSynchronization(status, definition);
		return status;
	}
	
	// org.springframework.transaction.support.AbstractPlatformTransactionManager#prepareSynchronization
	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());
			
			// step into ...
			TransactionSynchronizationManager.initSynchronization();
		}
	}
	
	// org.springframework.transaction.support.TransactionSynchronizationManager#initSynchronization
	public static void initSynchronization() throws IllegalStateException {
		if (isSynchronizationActive()) {
			throw new IllegalStateException("Cannot activate transaction synchronization - already active");
		}
		logger.trace("Initializing transaction synchronization");
		//	设置一个当前线程活跃的TransactionSynchronization空集合
		synchronizations.set(new LinkedHashSet<>());
	}

4.2 prepareTransactionInfo:初始化TransactionInfo并绑定到线程

	// 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() + "]");
			}
			// 创建新事务的TransactionStatus
			// 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.");
			}
		}

		// 将resourceHolder(ConnectHolder)绑定到当前线程
		// 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);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肯尼思布赖恩埃德蒙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值