spring源码事务二之传播机制核心源码

不同传播机制下怎么新建/获取事务主线代码解析

当前源码基于spring boot 2.1.6.RELEASE版本

新建或者获取事务原理简述

从ThreadLocal<Map<DataSource,ConnectionHolder>中获取当前事务,获取到有效的数据库连接connectionHolder,说明当前存在事务

1.如果不存在事务

  • 当前传播类型为MANDATORY抛出异常
  • 当前传播类型为REQUIRESNEW,NESTED,REQUIRE,创建并启动事务

2.如果存在事务

  • 当前传播类型为NEVER抛出异常
  • 当前传播类型为NOT_SUPPORTED挂起当前事务,但是不启动新事务
  • 当前传播类型为REQUIRESNEW 挂起当前事务,并且启动新事务
  • 当前传播类型为SUPPORTED,MANDATORY,REQUIRES 继续使用当前事务,不需要挂起当前事务和启动新事务

3.启动事务做了什么

  1. 创建新的数据库连接
  2. 设置用户定义的或者spring定义的属性并且设置autocommit为false
  3. 把创建的数据连接放入ThreadLocal<Map<DataSource,ConnectionHolder>中

4.挂起事务做了什么

  1. 把当前数据库连接从ThreadLocal<Map<DataSource,ConnectionHolder>中清除保存在SuspendedResourcesHolder对象中
  2. 把当前数据库连接从其他描述数据库连接或者事务信息的ThreaLocal中清除保存在SuspendedResourcesHolder对象中
  3. 把SuspendedResourcesHolder对象存储在DefaultTransactionStatus对象中,以方便后面恢复事务

1.当前不存在事务,不同传播机制是如何处理的

当前不存在事务
MANDATORY
抛出IllegalTransactionStateException
REQUIRESNEW
NESTED
REQUIRE
创建并启动事务
SUPPORTED
NEVER
NOTSUPPORTED
不启动新事务

org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

//org.springframework.transaction.support.AbstractPlatformTransactionManager

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
      //获取当前事务信息
   	Object transaction = doGetTransaction();

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

   	//不存在事务的处理
   	// 1.检查超时时间参数合法性,不合法抛出InvalidTimeoutException异常
   	if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
   		throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
   	}

      //当前不存在事务,当前方法定义的事务传播类型为MANDATORY时抛出异常
      
   	if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
   		throw new IllegalTransactionStateException(
   				"No existing transaction found for transaction marked with propagation 'mandatory'");
   	}
   	//当前不存在事务,当前方法定义的事务隔离级别为REQUIRES_NEW,PROPAGATION_NESTED,PROPAGATION_REQUIRED创建新的连接和事务
   
   	else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
   			definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
   			definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
   		SuspendedResourcesHolder suspendedResources = suspend(null);
   		if (debugEnabled) {
   			logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
   		}
   		try {
   			boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
   			DefaultTransactionStatus status = newTransactionStatus(
   					definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
   			doBegin(transaction, definition);
   			prepareSynchronization(status, definition);
   			return status;
   		}
   		catch (RuntimeException | Error ex) {
   			resume(null, suspendedResources);
   			throw ex;
   		}
   	}
   	//当前不存在事务,当前方法定义的事务隔离级别为SUPPORTED,NOT_SUPPORTED NEVER spring不会创建连接和事务
   	
   	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);
   	}
   }

2.当前存在事务,不同传播机制是如何处理的

当前存在事务
NEVER
抛出IllegalTransactionStateException
NOTSUPPORTED
挂起当前事务但不启动新事务
REQUIRESNEW
挂起当前事务并且启动新事务
NESTED
使用savePoint技术创建子事务
SUPPORTED
REQUIRES
MANDATORY
不挂起当前事务,也不创建新事务,继续使用当前事务
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction");
			}
			Object suspendedResources = suspend(transaction);
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction, creating new transaction with name [" +
						definition.getName() + "]");
			}
			//挂起事务
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			//新建事务
			try {
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
			catch (RuntimeException | Error beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
		}

		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			if (!isNestedTransactionAllowed()) {
				throw new NestedTransactionNotSupportedException(
						"Transaction manager does not allow nested transactions by default - " +
						"specify 'nestedTransactionAllowed' property with value 'true'");
			}
			if (debugEnabled) {
				logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
			}
			if (useSavepointForNestedTransaction()) {
				// Create savepoint within existing Spring-managed transaction,
				// through the SavepointManager API implemented by TransactionStatus.
				// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
				status.createAndHoldSavepoint();
				return status;
			}
			else {
				// Nested transaction through nested begin and commit/rollback calls.
				// Usually only for JTA: Spring synchronization might get activated here
				// in case of a pre-existing JTA transaction.
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, null);
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
		}

		// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
		if (debugEnabled) {
			logger.debug("Participating in existing transaction");
		}
		if (isValidateExistingTransaction()) {
			if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
				Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
					Constants isoConstants = DefaultTransactionDefinition.constants;
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] specifies isolation level which is incompatible with existing transaction: " +
							(currentIsolationLevel != null ?
									isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
									"(unknown)"));
				}
			}
			if (!definition.isReadOnly()) {
				if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] is not marked as read-only but existing transaction is");
				}
			}
		}
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}

3.事务是怎么启动的

  1. 新建数据库连接
  2. 数据库连接属性同步,比如隔离级别,连接超时时间,是否只读
  3. 数据库连接设置autoCommit为false
  4. 以DataSource为key,数据库连接为value,放入ThreadLocal中
  5. 同步更新其他保存当前数据库信息或者属性的ThreadLocal变量值

下面的思维导图红色部分才是精华,想快速了解的只需要看红色部分

org.springframework.jdbc.
datasource.DataSourceTransactionManager
#doBegin
当前线程没有数据库连接或者
数据库连接属性
SynchronizedWithTransaction为true
都会创建一个新的连接
1.设置数据库连接属性
SynchronizedWithTransaction为true
Transational注解定义的隔离级别同步到数据连接
2.Transation设置的的隔离级别
是否只读同步到数据库连接
org.springframework.jdbc
.datasource.DataSourceUtils
#prepareConnectionForTransaction
3.设置数据库连接的autocommit为false
4.如果数据库连接设置了只读
会执行SET TRANSACTION READ ONLY sql语句
5.设置数据连接的属性transactionActive为true
(数据连接设置为活跃)
6.连接超时时间同步到数据库连接
org.springframework.jdbc
.datasource.DataSourceTransactionManager
#prepareTransactionalConnection
7.如果是新建的连接
则把当前datasource为key
数据连接为value 放入threadLocal中
org.springframework.
transaction.support.
TransactionSynchronizationManager#bindResource
8.如果以上步骤抛出异常
释放当前数据库连接
并且把当前数据库连接置为空

org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction方法中开启事务的代码

boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
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 {
          //没有数据库连接或者数据库连接属性SynchronizedWithTransaction为true,都会创建一个新的连接
            if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
                Connection newCon = this.obtainDataSource().getConnection();
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
                }
                //设置新建的数库连接到transaction对象中,并设置isNewConnectionHolder为true,表示新创建的连接
                txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
            }
            //设置数据库连接属性SynchronizedWithTransaction为true
            txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
            con = txObject.getConnectionHolder().getConnection();
            //@Transation设置的的隔离级别,是否只读同步到数据库连接
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
            txObject.setPreviousIsolationLevel(previousIsolationLevel);
            //设置数据库连接的autocommit为false
            if (con.getAutoCommit()) {
                txObject.setMustRestoreAutoCommit(true);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
                }

                con.setAutoCommit(false);
            }
            //只读的数据库连接执行SET TRANSACTION READ ONLY sql语句
            this.prepareTransactionalConnection(con, definition);
            //设置数据连接transactionActive为true,数据连接为活跃
            txObject.getConnectionHolder().setTransactionActive(true);
            //从transational属性中超时时间同步到数据库连接
            int timeout = this.determineTimeout(definition);
            if (timeout != -1) {
                txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
            }
             //如果是新建的连接,则把当前的数据连接放入threadLocal
            if (txObject.isNewConnectionHolder()) {
                TransactionSynchronizationManager.bindResource(this.obtainDataSource(), txObject.getConnectionHolder());
            }

        } catch (Throwable var7) {
            if (txObject.isNewConnectionHolder()) {
                DataSourceUtils.releaseConnection(con, this.obtainDataSource());
                txObject.setConnectionHolder((ConnectionHolder)null, false);
            }

            throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7);
        }
    }

org.springframework.transaction.support.TransactionSynchronizationManager#bindResource

org.springframework.transaction.support.TransactionSynchronizationManager
以下变量,创建资源,挂起资源,恢复资源都需要更新

private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<>("Transactional resources");

	private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
			new NamedThreadLocal<>("Transaction synchronizations");

	private static final ThreadLocal<String> currentTransactionName =
			new NamedThreadLocal<>("Current transaction name");

	private static final ThreadLocal<Boolean> currentTransactionReadOnly =
			new NamedThreadLocal<>("Current transaction read-only status");

	private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
			new NamedThreadLocal<>("Current transaction isolation level");

	private static final ThreadLocal<Boolean> actualTransactionActive =
			new NamedThreadLocal<>("Actual transaction active");
private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<>("Transactional resources");

public static void bindResource(Object key, Object value) throws IllegalStateException {
        //根据datasource创建一个对象为Key,数据库连接为value,放入threadLocal
		Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
		Assert.notNull(value, "Value must not be null");
		Map<Object, Object> map = resources.get();
		// set ThreadLocal Map if none found
		if (map == null) {
			map = new HashMap<>();
			resources.set(map);
		}
		Object oldValue = map.put(actualKey, value);
		// Transparently suppress a ResourceHolder that was marked as void...
		if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) {
			oldValue = null;
		}
		if (oldValue != null) {
			throw new IllegalStateException("Already value [" + oldValue + "] for key [" +
					actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Bound value [" + value + "] for key [" + actualKey + "] to thread [" +
					Thread.currentThread().getName() + "]");
		}
	}

org.springframework.jdbc.datasource.DataSourceUtils#prepareConnectionForTransaction

  @Nullable
    public static Integer prepareConnectionForTransaction(Connection con, @Nullable TransactionDefinition definition) throws SQLException {
        Assert.notNull(con, "No Connection specified");
        //transation注解如果设置为只读,同步到连接
        if (definition != null && definition.isReadOnly()) {
            try {
                if (logger.isDebugEnabled()) {
                    logger.debug("Setting JDBC Connection [" + con + "] read-only");
                }

                con.setReadOnly(true);
            } catch (RuntimeException | SQLException var4) {
                for(Throwable exToCheck = var4; exToCheck != null; exToCheck = ((Throwable)exToCheck).getCause()) {
                    if (exToCheck.getClass().getSimpleName().contains("Timeout")) {
                        throw var4;
                    }
                }

                logger.debug("Could not set JDBC Connection read-only", var4);
            }
        }

        //transation的隔离级别同步到数据库连接
        Integer previousIsolationLevel = null;
        if (definition != null && definition.getIsolationLevel() != -1) {
            if (logger.isDebugEnabled()) {
                logger.debug("Changing isolation level of JDBC Connection [" + con + "] to " + definition.getIsolationLevel());
            }

            int currentIsolation = con.getTransactionIsolation();
            if (currentIsolation != definition.getIsolationLevel()) {
                previousIsolationLevel = currentIsolation;
                con.setTransactionIsolation(definition.getIsolationLevel());
            }
        }

        return previousIsolationLevel;
    }

org.springframework.jdbc.datasource.DataSourceTransactionManager#prepareTransactionalConnection

 protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition) throws SQLException {
        if (this.isEnforceReadOnly() && definition.isReadOnly()) {
            Statement stmt = con.createStatement();

            try {
                stmt.executeUpdate("SET TRANSACTION READ ONLY");
            } finally {
                stmt.close();
            }
        }

    }

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

4.事务是怎么挂起的

挂起事务
org.springframework
.transaction.support
.AbstractPlatformTransactionManager
#suspend
挂起TransactionSynchronization资源
org.springframework
.transaction.support.
AbstractPlatformTransactionManager
#doSuspendSynchronization
获取TransactionSynchronizationManager.synchronizations变量
并且依次调用变量存放的TransactionSynchronization的suspend方法
清空synchronizations变量
并返回原来存放的synchronizations变量
清空TransactionSynchronizationManager类的其他ThreadLocal变量

org.springframework.transaction.support.TransactionSynchronizationManager
以下变量,创建资源,挂起资源,恢复资源都需要更新

private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<>("Transactional resources");

	private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
			new NamedThreadLocal<>("Transaction synchronizations");

	private static final ThreadLocal<String> currentTransactionName =
			new NamedThreadLocal<>("Current transaction name");

	private static final ThreadLocal<Boolean> currentTransactionReadOnly =
			new NamedThreadLocal<>("Current transaction read-only status");

	private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
			new NamedThreadLocal<>("Current transaction isolation level");

	private static final ThreadLocal<Boolean> actualTransactionActive =
			new NamedThreadLocal<>("Actual transaction active");

org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction 片段
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction片段
看入参和出参数,入参数doGetTransaction获取DataSourceTransactionObject对象,挂起的资源存放在org.springframework.transaction.support.DefaultTransactionStatus对象中,getTransaction返回构建好的DefaultDefaultTransactionStatus对象

Object transaction = doGetTransaction();

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;
			}
	}
org.springframework.transaction.support.AbstractPlatformTransactionManager#suspend
@Nullable
	protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
	
	//TransactionSynchronizationManager.synchronizationActive这个Threaclocal变量不为null
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
		   // 挂起Synchronizations
	    // 获取TransactionSynchronizationManager.synchronizations变量,并且依次调用变量存放的TransactionSynchronization的suspend方法
	    //清空synchronizations变量,并返回原来存放的synchronizations变量
			List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
			try {
				Object suspendedResources = null;
				if (transaction != null) {
					suspendedResources = doSuspend(transaction);
				}
				//TransactionSynchronizationManager.currentTransactionName 存放事务名称设置为null
				String name = TransactionSynchronizationManager.getCurrentTransactionName();
				TransactionSynchronizationManager.setCurrentTransactionName(null);
				
				//TransactionSynchronizationManager.currentTransactionReadOnly设置为false
				boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
				TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
				
				//TransactionSynchronizationManager.CurrentTransactionIsolationLevel 存放隔离级别设置为false
				Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
				
				//TransactionSynchronizationManager.actualTransactionActive 设置为null
				boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
				TransactionSynchronizationManager.setActualTransactionActive(false);
				//把设置为null或者重新设置为默认值的threadLoal存储的构建成挂起资源返回
				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) {
			// Transaction active but no synchronization active.
			Object suspendedResources = doSuspend(transaction);
			return new SuspendedResourcesHolder(suspendedResources);
		}
		else {
			// Neither transaction nor synchronization active.
			return null;
		}
	}
org.springframework.transaction.support.AbstractPlatformTransactionManager#doSuspendSynchronization
private List<TransactionSynchronization> doSuspendSynchronization() {
       // 获取synchronizations变量(存放TransactionSynchronization),并且依次调用存放的TransactionSynchronization的suspend方法
		List<TransactionSynchronization> suspendedSynchronizations =
				TransactionSynchronizationManager.getSynchronizations();
		for (TransactionSynchronization synchronization : suspendedSynchronizations) {
			synchronization.suspend();
		}
			//清空synchronizations变量,并返回原来存放的synchronizations变量
		TransactionSynchronizationManager.clearSynchronization();
		return suspendedSynchronizations;
	}

org.springframework.transaction.support.TransactionSynchronizationManager.clearSynchronization

public static void clearSynchronization() throws IllegalStateException {
		if (!isSynchronizationActive()) {
			throw new IllegalStateException("Cannot deactivate transaction synchronization - not active");
		}
		//清空synchronizations变量
		logger.trace("Clearing transaction synchronization");
		synchronizations.remove();
	}

5.怎么获取当前事务

从Threalocal<Map<datasource,ConnectionHolder> 变量resources中根据dataSource获取对应的数据库连接

org.springframework.jdbc.datasource.DataSourceTransactionManager.doGetTransaction()
protected Object doGetTransaction() {
        DataSourceTransactionObject txObject = new DataSourceTransactionObject();
        //设置是否允许使用savepoint技术
        txObject.setSavepointAllowed(this.isNestedTransactionAllowed());
        //从threadLocal中过去数据库连接
        ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.obtainDataSource());
        txObject.setConnectionHolder(conHolder, false);
        return txObject;
    }
org.springframework.transaction.support.TransactionSynchronizationManager.getResource
private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<>("Transactional resources");
public static Object getResource(Object key) {
       
		Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
		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) {
		Map<Object, Object> map = resources.get();
		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;
	}

org.springframework.jdbc.datasource.DataSourceTransactionManager.isExistingTransaction

判断存在不存在事务,其实就是判断Thread<Map<DataSource,ConnectionHolder> resources 中有没有有效的数据库连接

protected boolean isExistingTransaction(Object transaction) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject)transaction;
        return txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive();
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值