学一学Spring中的@Transactional注解【上】

193 阅读9分钟

一、事务管理核心类及注解

1.1事务管理启动注解

 /**
  * 启用Spring注解驱动的事务管理功能,类似XML配置中的<tx:*>
  * 应用在@Configuration注解的配置类上
  * 配置传统的,命令式事务管理或者响应式事务管理
  */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Import(TransactionManagementConfigurationSelector.class)
 public @interface EnableTransactionManagement {
 ​
     /**
      * true:CGLIB
      * false:JDK动态代理
      * 注意两点:
      * 1、该设置只会影响需要代理的类以何种方式被代理,但是不能完全决定。
      * 2、这是一个全局的设置,将会影响所有spring管理需要被代理的bean。
      */
     boolean proxyTargetClass() default false;
 ​
     /**
      * 表名事务通知应该怎么被应用。
      * 默认值是AdviceMode.PROXY
      * 代理模式只允许通过代理拦截调用
      * 同一个类中的局部调用不会被拦截
      * 本地调用中方法上的@Transactional注解将被忽略,因为Spring的拦截器不会在此类运行时场景中发挥作用
      * 需要更高级的拦截模式,使用AdviceMode.ASPECTJ
      */
     AdviceMode mode() default AdviceMode.PROXY;
 ​
     /**
      * 同一个连接点上多个通知时,事务advisor的执行顺序
      */
     int order() default Ordered.LOWEST_PRECEDENCE;
 ​
 }

1.2事务管理配置选择器

 /**
  * 根据@EnableTransactionManagement中的模式,选择AbstractTransactionManagementConfiguration的实现。
  */
 public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
 ​
     /**
      * PROXY:ProxyTransactionManagementConfiguration
      * ASPECTJ:AspectJ(Jta)TransactionManagementConfiguration
      */
     @Override
     protected String[] selectImports(AdviceMode adviceMode) {
         switch (adviceMode) {
             // 默认情况
             case PROXY:
                 return new String[] {AutoProxyRegistrar.class.getName(),
                         ProxyTransactionManagementConfiguration.class.getName()};
             case ASPECTJ:
                 return new String[] {determineTransactionAspectClass()};
             default:
                 return null;
         }
     }
 ​
     private String determineTransactionAspectClass() {
         return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
                 TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
                 TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
     }
 ​
 }

1.3自动代理创建器

 /**
  * 基于@EnableTransactionManagement中的proxyTargetClass和adviceMode配置
  * 在BeanDefinitionRegistry上注册一个自动代理创建器
  */
 public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
 ​
     private final Log logger = LogFactory.getLog(getClass());
 ​
     @Override
     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
         boolean candidateFound = false;
         Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
         for (String annType : annTypes) {
             AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
             if (candidate == null) {
                 continue;
             }
             Object mode = candidate.get("mode");
             Object proxyTargetClass = candidate.get("proxyTargetClass");
             if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
                     Boolean.class == proxyTargetClass.getClass()) {
                 candidateFound = true;
                 if (mode == AdviceMode.PROXY) {
                     AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                     if ((Boolean) proxyTargetClass) {
                         AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                         return;
                     }
                 }
             }
         }
         if (!candidateFound && logger.isInfoEnabled()) {
             String name = getClass().getSimpleName();
             logger.info(String.format("%s was imported but no annotations were found " +
                     "having both 'mode' and 'proxyTargetClass' attributes of type " +
                     "AdviceMode and boolean respectively. This means that auto proxy " +
                     "creator registration and configuration may not have occurred as " +
                     "intended, and components may not be proxied as expected. Check to " +
                     "ensure that %s has been @Import'ed on the same class where these " +
                     "annotations are declared; otherwise remove the import of %s " +
                     "altogether.", name, name, name));
         }
     }
 ​
 }

1.4代理事务管理配置

 /**
  * 这个配置类配置了spring的一些基础设施bean,这些bean都是基于代理和注解驱动事务管理所需要的。
  */
 @Configuration(proxyBeanMethods = false)
 @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
     // advisor
     @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
     @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
     public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
             TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
 ​
         BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
         advisor.setTransactionAttributeSource(transactionAttributeSource);
         advisor.setAdvice(transactionInterceptor);
         if (this.enableTx != null) {
             advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
         }
         return advisor;
     }
     
     // 注解事务属性源
     @Bean
     @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
     public TransactionAttributeSource transactionAttributeSource() {
         return new AnnotationTransactionAttributeSource();
     }
     
     // advice
     @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;
     }
 ​
 }

1.5@Transactional

 /**
  * 在独立的方法或者类上描述一个事务属性。
  *  
  * 注解在类上,应用在该类及子类所有方法上。
  * 不会向上应用到父类上;
  * 继承的方法需要重新声明,才能参与到子类级别的注解应用中。
  *
  *
  * 如果在此注解中没有配置自定义回滚规则,则事务将对RuntimeException和Error进行回滚,但不会对已检异常进行回滚。
  *
  * 回滚规则决定在抛出给定异常时是否应该回滚事务,这些规则是基于模式的。模式可以是一个完全限定类名,
  * 也可以是一个异常类型的完全限定类名的子字符串(必须是Throwable的子类),目前不支持通配符。
  *
  * 回滚规则可以通过rollbackFor、noRollbackFor、rollbackForClassName、noRollbackForClassName配置,
  * 它们允许将模式分别指定为Class引用或String。
  *
  * 有关此注解中其他属性语义的具体信息,参考:
  * org.springframework.transaction.TransactionDefinition
  * org.springframework.transaction.interceptor.TransactionAttribute
  *
  * 事务管理
  *
  * 该注解通常与由PlatformTransactionManager管理的线程绑定事务一起工作,将事务暴露给当前执行线程内的所有数据访问操作。
  * 注意:这不会传播到方法内新启动的线程
  *
  */
 @Target({ElementType.TYPE, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 @Inherited
 @Documented
 public @interface Transactional {
 ​
     @AliasFor("transactionManager")
     String value() default "";
 ​
     @AliasFor("value")
     String transactionManager() default "";
 ​
     String[] label() default {};
 ​
     /**
      * 事务传播类型。
      * 默认是PROPAGATION_REQUIRED
      */
     Propagation propagation() default Propagation.REQUIRED;
 ​
     /**
      * 事务隔离级别
      * 默认值是Isolation.DEFAULT
      */
     Isolation isolation() default Isolation.DEFAULT;
 ​
     /**
      * 事务超时时间
      */
     int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
 ​
     String timeoutString() default "";
 ​
     /**
      * 只读标志
      */
     boolean readOnly() default false;
 ​
     /**
      * 定义0个或多个异常,它们必须是Throwable的子类,表示哪些异常类型必须导致事务回滚。
      */
     Class<? extends Throwable>[] rollbackFor() default {};
 ​
     String[] rollbackForClassName() default {};
 ​
     /**
      * 定义0个或多个异常,它们必须是hrowable的子类,表示哪些异常类型不进行事务回滚。
      */
     Class<? extends Throwable>[] noRollbackFor() default {};
 ​
     String[] noRollbackForClassName() default {};
 ​
 }
 ​

二、bean注册

2.1配置类事务相关注解解析

  • 实例化ConfigurationClassPostProcessor

  • 在容器中找到AppConfig这个配置类(@Configuration)

  • 解析配置类上的注解

  • 解析@Import注解时发现TransactionManagementConfigurationSelector

    1. 通过选择器找到AutoProxyRegistrar和ProxyTransactionManagementConfiguration
    2. 将AutoProxyRegistrar添加到AppConfig的importBeanDefinitionRegistrars中
    3. ProxyTransactionManagementConfiguration作为配置类继续解析
    4. 自身构建为beanDefinition,将@Bean注解的三个bean解析出来,外加一个父类的@Bean
  • 加载注册所有解析出来的bean定义信息(this.reader.loadBeanDefinitions(configClasses))

  • loadBeanDefinitionsFromRegistrars通过AutoProxyRegistrar将internalAutoProxyCreator注册到容器

2.2bean注册结果

invokeBeanFactoryPostProcessors(beanFactory)新增11个bean定义信息:

image-20241031140409280

  • jdbcTemplatetransactionManagerdataSource由主配置类Appconfig中的@Bean解析而来。
  • userServiceuserDaoImpl由组件扫描而来。
  • @EnableTransactionManagement中@Import引入的TransactionManagementConfigurationSelector选择器返回了配置类ProxyTransactionManagementConfiguration和注册器AutoProxyRegistrar。
  • AutoProxyRegistrar注册器注册了internalAutoProxyCreator
  • internalTransactionalEventListenerFactory是ProxyTransactionManagementConfiguration继承了AbstractTransactionManagementConfiguration,AbstractTransactionManagementConfiguration中的@Bean解析而来。
  • internalTransactionAdvisortransactionAttributeSourcetransactionInterceptor是配置类ProxyTransactionManagementConfiguration中@Bean解析而来。

三、bean实例化

3.1实例化结果

registerBeanPostProcessors(beanFactory)后新增3个单例:

image-20241031142944407

四、代理创建

4.1创建时机

  • 单例(如:UserService)构建过程中,初始化bean时(initializeBean),BeanPostProcessor(InfrastructureAdvisorAutoProxyCreator)会被应用
 // AbstractAutoProxyCreator
 // InfrastructureAdvisorAutoProxyCreator继承AbstractAutoProxyCreator,实现BeanPostProcessor
 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
     if (bean != null) {
         Object cacheKey = getCacheKey(bean.getClass(), beanName);
         if (this.earlyProxyReferences.remove(cacheKey) != bean) {
             return wrapIfNecessary(bean, beanName, cacheKey);
         }
     }
     return bean;
 }

InfrastructureAdvisorAutoProxyCreator

4.2创建过程

  • 查找所有的Advisor(当前容器中只有一个BeanFactoryTransactionAttributeSourceAdvisor)

  • 查找符合条件的Advisor(目标类中有方法有@Transactional注解)

    1. 遍历目标类的所有方法

      • 读取方法上@Transactional所有属性
      • 解析所有属性,构建RuleBasedTransactionAttribute
  • 代理工厂创建(ProxyFactory)

  • 创建CGLIB AOP代理(ObjenesisCglibAopProxy)

  • 获取callbacks(第一个还是DynamicAdvisedInterceptor[advised中的advisors中只有BeanFactoryTransactionAttributeSourceAdvisor])

  • 创建代理类并实例化

  • callbacks赋值(((Factory) proxyInstance).setCallbacks(callbacks))

  • 创建完成

4.3代理对象创建核心源码

 // AbstractAutoProxyCreator
 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
 ​
     // 查找能应用到bean上的Advice和Advisor
     Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
     if (specificInterceptors != DO_NOT_PROXY) {
         this.advisedBeans.put(cacheKey, Boolean.TRUE);
         // 创建代理
         Object proxy = createProxy(
                 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
         this.proxyTypes.put(cacheKey, proxy.getClass());
         return proxy;
     }
 ​
     this.advisedBeans.put(cacheKey, Boolean.FALSE);
     return bean;
 }
 // AbstractAdvisorAutoProxyCreator
 protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
     // 查找候选Advisor
     List<Advisor> candidateAdvisors = findCandidateAdvisors();
     // 查找符合条件的Advisor
     List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
     extendAdvisors(eligibleAdvisors);
     if (!eligibleAdvisors.isEmpty()) {
         eligibleAdvisors = sortAdvisors(eligibleAdvisors);
     }
     return eligibleAdvisors;
 }
 public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
     Assert.notNull(pc, "Pointcut must not be null");
     if (!pc.getClassFilter().matches(targetClass)) {
         return false;
     }
 ​
     MethodMatcher methodMatcher = pc.getMethodMatcher();
     if (methodMatcher == MethodMatcher.TRUE) {
         // No need to iterate the methods if we're matching any method anyway...
         return true;
     }
 ​
     IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
     if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
         introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
     }
 ​
     Set<Class<?>> classes = new LinkedHashSet<>();
     if (!Proxy.isProxyClass(targetClass)) {
         classes.add(ClassUtils.getUserClass(targetClass));
     }
     classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
     
     for (Class<?> clazz : classes) {
         Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
         // 遍历方法
         for (Method method : methods) {
             if (introductionAwareMethodMatcher != null ?
                     introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                     // methodMatcher是TransactionAttributeSourcePointcut
                     methodMatcher.matches(method, targetClass)) {
                 return true;
             }
         }
     }
 ​
     return false;
 }
// TransactionAttrobuteSourcePointcut
public boolean matches(Method method, Class<?> targetClass) {
    TransactionAttributeSource tas = getTransactionAttributeSource();
    // getTransactionAttribute如果不为空说明该方法上有@Transactional,且属性值已经被解析好构建了规则对象
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
// CglibAopProxy
public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
		}

		try {
			// 省略部分代码...

			// 创建配置CGLIB Enhancer...
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
			
            // 0号位 DynamicAdvisedInterceptor(BeanFactoryTransactionAttributeSourceAdvisor)
			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// 创建代理class并实例化,设置callbacks
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		// 省略部分代码...
	}

五、方法拦截

5.1拦截入口

 // CglibAopProxy.DynamicAdvisedInterceptor
 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
     Object oldProxy = null;
     boolean setProxyContext = false;
     Object target = null;
     TargetSource targetSource = this.advised.getTargetSource();
     try {
         // 省略部分代码...
         
         // 符合条件的拦截器链 TransactionInterceptor
         List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
         Object retVal;
         // 省略部分代码...
         
         // 方法调用
         retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
         
         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);
         }
     }
 }

5.2拦截过程

  1. 获取事务对象
  2. 根据事务的传播特性及额外配置,处理事务(创建新的、抛异常、挂起等)
  3. 开始事务
  4. 封装事务信息
  5. 目标对象方法调用
  6. 根据方法调用情况(正常、异常)处理事务

5.3事务拦截核心源码

 // TransactionAspectSupport
 protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
             final InvocationCallback invocation) throws Throwable {
 ​
     TransactionAttributeSource tas = getTransactionAttributeSource();
     // RuleBasedTransactionAttribute PROPAGATION_REQUIRED,ISOLATION_DEFAULT(@Transactional中默认)
     final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
     // 决定事务管理器
     // 从容器中取到默认的事务管理器 DataSourceTransactionManager
     final TransactionManager tm = determineTransactionManager(txAttr);
 ​
     // 省略部分代码...
     
     // 类型转换成PlatformTransactionManager
     PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
     // com.lazy.snail.service.UserService.createUser
     final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
     
     if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
         // 根据需要创建事务
         TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
 ​
         Object retVal;
         try {
             // 这是一个包裹通知: 调用拦截器链中的下一个拦截器
             // 通常会调用目标对象
             retVal = invocation.proceedWithInvocation();
         } catch (Throwable ex) {
             // 目标对象调用产生异常
             // 根据配置信息回滚或提交事务
             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;
     }
     // 省略部分代码...
 }
 ​
 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) {
             // 获取事务
             status = tm.getTransaction(txAttr);
         } else {
             if (logger.isDebugEnabled()) {
                 logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
                         "] because no transaction manager has been configured");
             }
         }
     }
     return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
 }
 ​
 protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
             @Nullable TransactionAttribute txAttr, String joinpointIdentification,
             @Nullable TransactionStatus status) {
 ​
     TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
     if (txAttr != null) {
         if (logger.isTraceEnabled()) {
             logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
         }
         txInfo.newTransactionStatus(status);
     } else {
         if (logger.isTraceEnabled()) {
             logger.trace("No need to create transaction for [" + joinpointIdentification +
                     "]: This method is not transactional.");
         }
     }
 ​
     // 事务信息绑定到线程
     txInfo.bindToThread();
     return txInfo;
 }
 // AbstractPlatformTransactionManager
 public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
             throws TransactionException {
 ​
     // 如果没有给事务定义信息,使用默认的
     TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
     
     // 拿到事务对象
     Object transaction = doGetTransaction();
     
     // 检查事务是否已经存在
     if (isExistingTransaction(transaction)) {
         // 事务被找到 -> 检查传播行为决定如何执行
         return handleExistingTransaction(def, transaction, debugEnabled);
     }
 ​
     // 检查新事务的定义设置
     if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
         throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
     }
 ​
     // 事务没找到找到 -> 检查传播行为决定如何处理
     // 如果没有事务,传播特性是PROPAGATION_MANDATORY,抛出异常
     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) {
         // 传播行为是PROPAGATION_REQUIRED || PROPAGATION_REQUIRES_NEW || PROPAGATION_NESTED
         
         // 挂起当前线程所有的事务同步对象,挂起的事务同步对象和其他事务相关的状态信息保存到 SuspendedResourcesHolder 对象
         // 事务传播行为为 PROPAGATION_REQUIRES_NEW 时,当前事务需要被挂起,以便开始一个新的事务。
         SuspendedResourcesHolder suspendedResources = suspend(null);
         if (debugEnabled) {
             logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
         }
         try {
             // 开始事务
             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);
     }
 }