SpringBoot系列:事物创建过程(二)

这篇具有很好参考价值的文章主要介绍了SpringBoot系列:事物创建过程(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringBoot事物创建过程

同系列

SpringBoot系列:事物加载过程(一)
SpringBoot系列:事物创建过程(二)
SpringBoot系列:事物提交回滚过程(三)

一、前言

上一节讲述了事物的加载过程,最后生成代理文件,放到spring容器中。

public class CloudDiskShareInfoDetailServiceImpl$$EnhancerBySpringCGLIB$$ec4fb618
extends CloudDiskShareInfoDetailServiceImpl
implements SpringProxy,Advised,Factory {
    ··· 省略
    @Override
    public final void aaa(Integer n) {
        MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
        if (methodInterceptor == null) {
            CloudDiskShareInfoDetailServiceImpl$$EnhancerBySpringCGLIB$$ec4fb618.CGLIB$BIND_CALLBACKS(this);
            methodInterceptor = this.CGLIB$CALLBACK_0;
        }
        if (methodInterceptor != null) {
            1、执行代理方法
            Object object = methodInterceptor.intercept(this, CGLIB$aaa$0$Method, new Object[]{n}, CGLIB$aaa$0$Proxy);
            return;
        }
        super.aaa(n);
    }
   ··· 省略
   
}

代理类继承了 被代理类,

实现了两个SpringProxy,Advised,Factory接口,

methodInterceptorDynamicAdvisedInterceptor

为什么实现了这三个接口?为什么是这个拦截器?

原理请跳转 :SpringAop解析的代码块十七之后

二、DynamicAdvisedInterceptor & intercept

@Override
		@Nullable
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Object target = null;
            1、获取的被代理类,也就是原始类
			TargetSource targetSource = this.advised.getTargetSource();
			try {
                2、是否对外暴露
				if (this.advised.exposeProxy) {
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				target = targetSource.getTarget();
				Class<?> targetClass = (target != null ? target.getClass() : null);
                3、获取符合条件的增强器 如事物的 TransactionInterceptor
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
                4、没有增强器,直接执行 被代理方法
				if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
					Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
					retVal = invokeMethod(target, method, argsToUse, methodProxy);
				}
				else {
                    5、递归调用process方法,处理所有的拦截器。
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
                6、最终返回值
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null && !targetSource.isStatic()) {
					targetSource.releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}

3、获取符合条件的增强器 这儿在AOP加载过程中,获取符合条件的增强逻辑几乎一致,不再做讲解了。

事物的话就是获取的 TransactionInterceptor,如果是我们常用的如@Before、@After、@Around则会是对应的拦截器,在各自的拦截器内部再次调用process方法,完成整个拦截器链的调用。

5、递归调用process方法,处理所有的拦截器。

具体调用流程解析请跳转:

AOP系列之执行流程

三、ReflectiveMethodInvocation & proceed

public Object proceed() throws Throwable {
    // We start with an index of -1 and increment early.
    1、最后一个拦截器,直接调用目标方法
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }
	2、根据下标获取对应的拦截器,并执行
    Object interceptorOrInterceptionAdvice =
        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    3、动态拦截器,判断是否匹配之后再调用
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
        if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
            return dm.interceptor.invoke(this);
        }
        else {
            return proceed();
        }
    }
    4、静态拦截器执行
    else {
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

这儿我们只分析事物是怎么执行的。

四、TransactionInterceptor & invoke

public Object invoke(MethodInvocation invocation) throws Throwable {
    1、被代理的原始类
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
        @Override
        @Nullable
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
        @Override
        public Object getTarget() {
            return invocation.getThis();
        }
        @Override
        public Object[] getArguments() {
            return invocation.getArguments();
        }
    });
}

事物相关所有的流程都在 invokeWithinTransaction中进行解析的。

五、invokeWithinTransaction

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {
		1AnnotationTransactionAttributeSource事物属性资源获取,也就是一开始注入的
		TransactionAttributeSource tas = getTransactionAttributeSource();
    	1.1、获取事物的属性,@Transaction的属性,如隔离级别,超时等
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    	2、确定事物管理器,这儿是jdbc的,也可自己设置
		final TransactionManager tm = determineTransactionManager(txAttr);

		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			···响应式事物的处理
		}
		3、获取事物管理器
		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
    	3.1com.zgf.service.impl.CloudDiskShareInfoDetailServiceImpl.aaa,得到方法的全路径
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		4、进入if,说明不是CallbackPreferringPlatformTransactionManager,也是声明式事物
		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
            5、创建并开启事务
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
                6、再次回调process方法,有可能直接执行被代理方法。
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
                7、事物异常的相关处理
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
                8、清除一些事物的标记,如在ThreadLocal内的一些事物信息
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}
			9、事物正常执行的提交操作
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			···编程式事物处理流程
			}
			···省略一堆 catch
			return result;
		}
	}

这儿有三种事物的处理方式:

1、声明式事物:@Transactiion

2、编程式事物

3、响应式事物:ReactiveTransactionManager,笔者也不太了解这种方式,有大佬的话请多多指点指点。

我们这儿只对声明式事务进行解析。

事物全流程

  • 开启事物
  • 执行目标放啊
  • 做出对应的处理:异常处理或提交处理

六、创建开启事物

6.1、createTransactionIfNecessary

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

		//标记名称
		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) {
                1、创建事物
				status = tm.getTransaction(txAttr);
			}
		}
    	2、创建TransactionInfo,并将事物信息保存到ThreadLocalreturn prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}

6.2、getTransaction

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException {
		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
		1、获取一个事物对象
		Object transaction = doGetTransaction();
		boolean debugEnabled = logger.isDebugEnabled();
		2、已经存在事物了,出现嵌套事务,根据事物隔离级别做出不同的处理
		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			return handleExistingTransaction(def, transaction, debugEnabled);
		}
		2.1、到这儿说明是第一次进来,还未开启事物
		// Check definition settings for new transaction.
    	校验超时时间是否符合规则,也就是不能为负数,但-1是不设置超时
		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.
    	3、检查事物传播行为,到这儿说明之前没有事物,该传播行为需要有事物所以抛出异常
		if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
    	3.1、这三种传播行为都是需要创建新的事物
		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 {
                4、创建新的事物
				return startTransaction(def, transaction, debugEnabled, suspendedResources);
			}
			catch (RuntimeException | Error ex) {
				resume(null, suspendedResources);
				throw ex;
			}
		}
		else {
            5、否则,配置的事务的传播行为就是剩下的三种:PROPAGATION_SUPPORTS或PROPAGATION_NEVER或PROPAGATION_NOT_SUPPORTED,这三种都是以非事物的方式运行的
			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);
			}
            5.1、 为给定参数创建一个新的TransactionStatus,并在适当时初始化事务同步,但是不会真正开启事务。
        		和startTransaction相比,其内部会调用newTransactionStatus和prepareSynchronization,但不会调用doBegin方法
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
		}
	}

6.3、doGetTransaction(获取数据库链接以及事物信息)

@Override
protected Object doGetTransaction() {
    1、初始化一个数据源对象,持有数据源信息以及事物信息
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    2、设置是否允许保存点,一般都是允许的,用于嵌套事物
    txObject.setSavepointAllowed(isNestedTransactionAllowed());
    3、第一次开启事物是null,后续会进行填充,若嵌套事物则不为null,所以嵌套事物用的都是同一个数据库链接
    ConnectionHolder conHolder =
        (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
    4false:不是新的事物,后面会重新判断若是第一次会设置为true
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
}

6.4、suspend 挂起事物

protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
    1、判断事物是否同步激活
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        2、执行挂起事物的同步回调方法,有具体的子类实现
        List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
        try {
            Object suspendedResources = null;
            if (transaction != null) {
                3、真正的挂起
                suspendedResources = doSuspend(transaction);
            }
            4、清空一些同步信息:名称、只读状态、隔离级别、激活状态
            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);
            5、将上述信息进行包装返回
            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.
        6、事物不是激活状态,但是存在事物,直接挂起
        Object suspendedResources = doSuspend(transaction);
        return new SuspendedResourcesHolder(suspendedResources);
    }
    else {
        // Neither transaction nor synchronization active.
        7、没有事物,返回null
        return null;
    }
}

6.5、doSuspendSynchronization

private List<TransactionSynchronization> doSuspendSynchronization() {
    1、获取线程的所有同步事物
    List<TransactionSynchronization> suspendedSynchronizations =
        TransactionSynchronizationManager.getSynchronizations();
    2、依次挂起事物
    for (TransactionSynchronization synchronization : suspendedSynchronizations) {
        synchronization.suspend();
    }
    3、清空同步事物
    TransactionSynchronizationManager.clearSynchronization();
    return suspendedSynchronizations;
}

6.6、startTransaction开启事物

private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
                                           boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
	1、传播方式是无需事物,则新建标志设置为false
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    2、status:持有新事物的信息,以及之前挂起的事物信息
    DefaultTransactionStatus status = newTransactionStatus(
        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    doBegin(transaction, definition);
    3、绑定TransactionSynchronizationManager内的一系列线程资源如:
       名称、只读状态、隔离级别、激活状态等
    prepareSynchronization(status, definition);
    return status;
}



protected DefaultTransactionStatus newTransactionStatus(
    TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
    boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
	1、newSynchronization:是否是新事物
    2、第二个判断,因为之前挂起事物清空了同步信息,这儿也是未激活状态
    boolean actualNewSynchronization = newSynchronization: &&
        !TransactionSynchronizationManager.isSynchronizationActive();
    3、返回全新的事物信息
    return new DefaultTransactionStatus(
        transaction, newTransaction, actualNewSynchronization,
        definition.isReadOnly(), debug, suspendedResources);
}

6.7、doBegin 真正的开启事物的地方

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

		try {
            1、是否存在链接,第一次开始事物是不存在的 || 事物同步状态 默认false下面创建完之后会设置ture
			if (!txObject.hasConnectionHolder() ||
					txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
				Connection newCon = obtainDataSource().getConnection();
				if (logger.isDebugEnabled()) {
					logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
				}
                1.1、设置链接,并标记为新的链接
				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
			}

			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			con = txObject.getConnectionHolder().getConnection();
			2、设置隔离级别
			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			txObject.setPreviousIsolationLevel(previousIsolationLevel);
            3、设置只读模式
			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).
            4、是否自动提交,改为手动
			if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				}
				con.setAutoCommit(false);
			}
			5、开启数据库事物的只读模式,会优化查询
			prepareTransactionalConnection(con, definition);
			txObject.getConnectionHolder().setTransactionActive(true);
			6、设置超时时间
			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

			// Bind the connection holder to the thread.
             7、上面设置的新的链接标志
			if (txObject.isNewConnectionHolder()) {
			 7.1、绑定资源,就是绑定TransactionSynchronizationManager的resources
                 前面用resources做了一系列处理,如事物挂起,就是获取的该资源进行依次挂起
				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);
		}
	}

七、处理嵌套事物

接上述 6.2 中的 2,如果已经存在事物了如何处理。

7.1、handleExistingTransaction(嵌套事物的处理)

	private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {
		1、非事物方式运行,不允许事物出现,直接抛出异常
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}
		2、非事物方式运行,若存在事物,则挂起,执行完之后恢复事物继续执行
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction");
			}
            2.1、挂起事物返回挂起信息
			Object suspendedResources = suspend(transaction);
            2.2、是否更新同步信息 TransactionSynchronizationManager内的一系列threadlocal属性
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
            2.3、创建事物状态信息
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}
		3、每次都开启一个新的事物,挂起原来的事物
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction, creating new transaction with name [" +
						definition.getName() + "]");
			}
            3.1、挂起原事物
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			try {
                3.2、开启新事物
				return startTransaction(definition, transaction, debugEnabled, suspendedResources);
			}
			catch (RuntimeException | Error beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
		}
		4、如果当前有事物,则在事物内执行,通过保存点的方式进行回滚,但提交的话是交由外层事物提交。
		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);
                4.2、创建保存点
				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.
                4.3、通常用于JTA:开启新事物
				return startTransaction(definition, transaction, debugEnabled, null);
			}
		}

		// 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");
				}
			}
		}
        5、剩下的传播行为就是PROPAGATION_SUPPORTS或者PROPAGATION_REQUIRED,不会有PROPAGATION_MANDATORY。
          直接参与当前事务执行。
            
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}

挂起之后都返回了挂起的资源,重新设置到事物信息中去。

7.2、createAndHoldSavepoint 创建保存点

	public void createAndHoldSavepoint() throws TransactionException {
		setSavepoint(getSavepointManager().createSavepoint());
	}

设置的保存点:SAVEPOINT_ + 数字形式,如 SAVEPOINT_1

八、总结

到这儿事物的创建已经解析完毕,下一章开始执行完本体方法之后的处理,回滚or提交

1、事物是在AOP内执行的,递归的调用process方法,从而进入对应拦截器的invoke方法,事物进入的就是TransactionInterceptor,事物之旅正式开启。

2、 获取一些事物属性,以及事物管理器,准备着手开始创建事物。

3、首先判断是否已经存在事物,若存在则是嵌套事物按照嵌套事物的处理方式进行处理。

​ 3.1、根据不同的传播行为做出不同的处理方式,如PROPAGATION_REQUIRES_NEW,策略就是挂起原事物,开启新的事物等,具体说明放在最后。

4、不存在事物,则准备开启事物,(不同的传播行为有的会抛出异常,有的创建事物,有的以空事物的方式运行)。

5、设置一系列的事物信息,如隔离级别、只读、手动提交、真正开启事物的方法doBegin方法,从数据库连接池获取一个新的链接,正式开启事物,最终同步spring事物管理器的信息放到threadLocal中,所以为什么说事物不支持多线程文章来源地址https://www.toymoban.com/news/detail-405897.html

事务传播行为类型 未开启事物 已开启事物 综合说明
PROPAGATION_REQUIRED 默认的传播行为,开启事物。 加入到前一个事物中 若存在事物加入到前一个事物中去,若不存在事物则开启新的事物
PROPAGATION_SUPPORTS 空事物运行 加入到前一个事物 存在事物则加入到前一个事物中去,不存在事物则以空事物运行。
PROPAGATION_NOT_SUPPORTED 创建空事物 将前一个事物挂起,空事物运行。 寸在事物则将事物挂起,创建空事物,不存在则创建空事物。
PROPAGATION_REQUIRES_NEW 创建新事物 挂起前一个,创建新事物 无论是否存在事物,都开启新的事物
PROPAGATION_MANDATORY 抛出异常 使用当前事物 存在事物则加入,不存在抛异常
PROPAGATION_NEVER 空事物运行 抛出异常 存在事物抛出异常,不存在事物创建空事物
PROPAGATION_NESTED 创建新事物 嵌套在内部,通过保存点的方式进行回滚,本质还是一个事物 存在事物,创建保存点加入到事物中,不存在开启新事物

到了这里,关于SpringBoot系列:事物创建过程(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • IDEA+maven+Springboot工程创建超详细过程示例

    参考链接: Maven下载安装及IDEA配置Maven的超详细教程   SpringBoot是由Pivotal团队提供的全新框架,qit设计的目的主要是用来简化Spring应用的初始搭建易婧开发过程。该框架使用了特定的方式进行配置,从而使开发人员不再需要定义样板化的配置。简单来说就是Springboot不是什么

    2024年02月05日
    浏览(47)
  • springboot系列一:超详细一步步创建springboot项目

    将maven仓库设置为阿里云仓库,不然依赖会下载很慢(亲身体验过,两个小时左右,而且还会超时,所以在创建项目前,一定要先设置好maven)。 settings.xml 项目依赖可以在项目创建后,在pom.xml中配置。也可以在项目创建时引入。 Developer Tools Spring Boot DevTools 项目重启,热更新

    2024年02月10日
    浏览(30)
  • 【Spring框架全系列】如何创建一个SpringBoot项目

    🌇哈喽,大家好,我是小浪。前几篇博客我们已经介绍了什么是Spring,以及如何创建一个Spring项目,OK,那么单单掌握Spring是完全不够的,Spring的家族体系十分强大,我们还需要深入学习,以便于我们后续达到能独立做项目的水平。今天我们来学习SpringBoot。🏜 📲目录 一、

    2024年02月03日
    浏览(46)
  • k8s系列-kuboard创建工作负载 docker上传java微服务jar包到仓库的过程

    1.查看环境中是否存在docker环境 docker version 2.不存在的话需要创建docker 1.环境说明 1.开发人员将java微服务打包成在linux中可运行的jar包,将其传送给运维人员 2.外网和内网可以传送文件 3.内网需要有linux服务器,并且配置了docker环境和命名空间 这里过程是基于k8s的集群kuoard控

    2024年02月05日
    浏览(39)
  • mybatis事物是如何和spring事物整合的

    目录 1、mybatis事物管理器 2、SpringManagedTransactionFactory如何处理事物 3、spring事物如何设置connection连接到threadLocal 1、mybatis事物管理器 mybatis事物抽象接口类:Transaction。该接口定义了事物基本方法和获取数据库连接方法  该类有三个实现类JdbcTransaction、ManagedTransaction、SpringMan

    2024年02月15日
    浏览(38)
  • es 创建索引过程

    一、创建索引 二、索引设置别名 三、创建角色 四、创建用户

    2024年02月07日
    浏览(29)
  • java对象创建的过程

    2024年02月11日
    浏览(33)
  • java对象的创建过程

    一.类的加载与检查 当我们new了一个对象的时候,首先会去检查一下这个指令是否在常量池中存在符号引用,并且检查这个符号引用代表的对象是否被加载,解析初始化过,如果没有就要先去进行类加载过程 二.分配内存 我们通过第一步的检查后,就会在堆中划分出一块对象

    2024年02月06日
    浏览(36)
  • js创建 ajax 过程

    🙂博主:锅盖哒 🙂文章核心: js创建 ajax 过程 目录 前言:AJAX 技术的重要性 详解:创建 AJAX 请求的步骤 1. 创建 XMLHttpRequest 对象 2. 配置请求 3. 处理响应 4. 发送请求 5. 处理异步请求 解析:AJAX 请求的重要性和限制 总结: 前言:AJAX 技术的重要性 Asynchronous JavaScript and XML(

    2024年02月08日
    浏览(32)
  • JVM中对象创建过程

    在JVM中对象的创建,我们从一个new指令开始: 这个过程大概图示如下: 虚拟机收到new指令触发。 类加载检查:如果类没有被类加载器加载,则执行类加载流程(将class信息加载到JVM的运行时数据区的过程),对象所需内存大小在类加载完后可以完全确定。 对象分配内存:从

    2024年03月22日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包