Spring声明式事务管理

关键词:声明式事务管理    @Transactional

 


Spring使用Spring AOP实现了统一的事务管理,而Spring AOP又是依赖于动态代理的实现。下面我以介绍类的形式,来描述在一个简单的注解@Transactional实现声明式事务的背后,Spring做了哪些工作。

 Spring源码版本:4.3.5


█ 事务管理

  • PlatformTransactionManager

事务管理接口,完成对事务的管理和操作,比如开启事务,提交和回滚事务。通过实现此接口,完成对已经创建的事务进行操作。

package org.springframework.transaction;

public interface PlatformTransactionManager {
    // 获取事务对象,方法返回一个全新的事务或者返回当前调用栈中匹配的已存在的事务
    // start transaction或begin
    TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException;
    // 提交事务
    // commit;
    void commit(TransactionStatus var1) throws TransactionException;
    // 回滚事务
    // rollback
    void rollback(TransactionStatus var1) throws TransactionException;
}
  • TransactionStatus

事务对象,可以理解成是MySQL数据库中的事务在Spring中的一种实现。

package org.springframework.transaction;

import java.io.Flushable;

public interface TransactionStatus extends SavepointManager, Flushable {
    boolean isNewTransaction();

    boolean hasSavepoint();

    void setRollbackOnly();

    boolean isRollbackOnly();

    void flush();

    boolean isCompleted();
}
package org.springframework.transaction;

// 事务中的保存点,即MySQL中savepoint功能
public interface SavepointManager {
    // 在事务中创建一个保存点
    // savepoint 别名;
    Object createSavepoint() throws TransactionException;
    // 回滚保存点内的事务操作
    // rollback to savepoint 别名;
    void rollbackToSavepoint(Object var1) throws TransactionException;
    // 撤销保存点,扔保留事务操作
    // release savepoint 别名;
    void releaseSavepoint(Object var1) throws TransactionException;
}
  • TransactionDefinition

事务定义,定义事务的隔离级别传播机制,超时时间等。Spring根据定义来创建和控制事务对象。比如在MySQL的InnoDB存储引擎中也可以设置事务的隔离级别。

package org.springframework.transaction;

public interface TransactionDefinition {
    // 传播机制
    int PROPAGATION_REQUIRED = 0;
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    int PROPAGATION_NOT_SUPPORTED = 4;
    int PROPAGATION_NEVER = 5;
    int PROPAGATION_NESTED = 6;
    // 隔离级别,与InnoDB存储引擎的四个隔离级别对应
    int ISOLATION_DEFAULT = -1;
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    // 超时时间
    int TIMEOUT_DEFAULT = -1;

    int getPropagationBehavior();

    int getIsolationLevel();

    int getTimeout();
    // 是否只读,MySQL中只读事务命令:start transaction read only;
    // 读写都可以:start transaction或start transaction read write; 
    // 只读表示只能select表,无法update与delete表
    boolean isReadOnly();

    String getName();
}
  • AbstractPlatformTransactionManager

抽象类,实现了PlatformTransactionManager接口。提供了一些默认的方法实现,比如提交和回滚的逻辑实现。一般自定义事务管理类的时候,不是直接去实现PlatformTransactionManager接口,而是通过继承AbstractPlatformTransactionManager来完成,AbstractPlatformTransactionManager的作用就相当于一个模板,提供固有的方法实现,我们可以在其基础上,完成剩下的属于自己的逻辑,这样按照既有的套路,可以减轻开发者很多工作。

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable

比如commit方法的实现:

public final void commit(TransactionStatus status) throws TransactionException {
    if (status.isCompleted()) {
        throw new IllegalTransactionStateException("Transaction is already completed - do not call commit or rollback more than once per transaction");
    } else {
        DefaultTransactionStatus defStatus = (DefaultTransactionStatus)status;
        if (defStatus.isLocalRollbackOnly()) {
            if (defStatus.isDebug()) {
                this.logger.debug("Transactional code has requested rollback");
            }

            this.processRollback(defStatus);
        } else if (!this.shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
            if (defStatus.isDebug()) {
                this.logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
            }

            this.processRollback(defStatus);
            if (status.isNewTransaction() || this.isFailEarlyOnGlobalRollbackOnly()) {
                throw new UnexpectedRollbackException("Transaction rolled back because it has been marked as rollback-only");
            }
        } else {
            this.processCommit(defStatus);
        }
    }
}
  • AbstractTransactionStatus

既然对于PlatformTransactionManager有默认的抽象类方法实现模板,那TransactionStatus也有,其对应的模板实现类就是AbstractTransactionStatus。

public abstract class AbstractTransactionStatus implements TransactionStatus
  • DefaultTransactionDefinition

TransactionDefinition没有提供对应的抽象类,而是直接提供了一个默认的实现类DefaultTransactionDefinition。我感觉是因为TransactionDefinition的主要的内容是属性,方法比较简单,就没有必要提供一个抽象模板实现了。

public class DefaultTransactionDefinition implements TransactionDefinition, Serializable
  • DataSourceTransactionManager

Spring默认提供了多种方式的事务管理实现类,这些类统一继承自AbstractPlatformTransactionManager抽象类,比如:DataSourceTransactionManager、HibernateTransactionManager、JpaTransactionManager等分别适应不同的场景来做事务管理。DataSourceTransactionManager面向数据源做事务管理,HibernateTransactionManager为Hibernate提供事务管理,JpaTransactionManager为Jpa提供事务管理。

public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean

█ 事务服务

这个章节之所以叫事务服务,是描述了为什么在利用Spring进行声明式事务管理的时候,我们只需要在目标方法上配置@Transactional注解即可。下面我们来看看Spring是如何一步步的完成背后的工作的。

声明式事务主要通过注解或XML配置就能完成对方法中事务的管理,内部实现的细节已经被Spring封装好,我们使用的时候可以拿过来直接配置注解即可。

Spring官网的声明式事务工作原理图:

①在实际使用中,要调用代理对象的方法,而不是实际对象的方法

②声明式事务管理功能是通过AOP实现的,而AOP又是建立在JDK或CGLIB动态代理上实现的。

③在代理对象中完成实际方法的调用,以及在实际方法调用之后根据情况提交或回滚事务。

<关于动态代理的内容,请戳《JDK动态代理》《CGLIB动态代理》>

下面是我根据Spring声明式事务功能的启动过程画的图,您可以根据图中的类再结合下文来了解:

  • @EnableTransactionManagement

负责启动Spring事务功能,从这里开始,主要指导相关的类完成自己负责的功能,比如扫描@Transactional注解,根据注解产生代理对象等等。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
    // mode配置的值是AdviceMode.PROXY时起作用,false表示基于接口生成代理对象(JDK动态代理),true表示基于类生成代理对象(CGLIB动态代理)
    boolean proxyTargetClass() default false;
    // PROXY表示使用Spring AOP完成事务的功能
    // ASPECTJ表示使用Spring ASPECTJ完成事务的功能
    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}
  • TransactionManagementConfigurationSelector

在@EnableTransactionManagement中,@Import注解会向Spring容器中注册TransactionManagementConfigurationSelector,接下来的功能转移到TransactionManagementConfigurationSelector中,Spring会根据返回值向容器中注册相应的对象,比如默认配置会注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    public TransactionManagementConfigurationSelector() {
    }
    // 根据@EnableTransactionManagement注解配置的AdviceMode,来区分功能实现,往Spring容器中注册不同的bean
    protected String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
        // 默认实现,向Spring容器中注册AutoProxyRegistrar与ProxyTransactionManagementConfiguration两个对象,后面的事情转交给他们俩    
        case PROXY:
            return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
        case ASPECTJ:
            return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
        default:
            return null;
        }
    }
}
  • AutoProxyRegistrar

当@EnableTransactionManagement注解中的mode配置成PROXY才此类的逻辑才真正干活,mode=PROXY表示使用Spring AOP完成事务的功能。主要干的活就是往Spring容器中注册InfrastructureAdvisorAutoProxyCreator。

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    boolean candidateFound = false;
    Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
    Iterator var5 = annoTypes.iterator();

    while(var5.hasNext()) {
        String annoType = (String)var5.next();
        AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
        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) {
        String name = this.getClass().getSimpleName();
        this.logger.warn(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));
    }

}
  • ProxyTransactionManagementConfiguration

主要完成的功能就是向Spring容器中注册AnnotationTransactionAttributeSource、BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    public ProxyTransactionManagementConfiguration() {
    }
    
    // 向Spring容器中注册BeanFactoryTransactionAttributeSourceAdvisor
    @Bean(
        name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
    )
    @Role(2)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(this.transactionAttributeSource());
        advisor.setAdvice(this.transactionInterceptor());
        advisor.setOrder((Integer)this.enableTx.getNumber("order"));
        return advisor;
    }
    
    // 向Spring容器中注册AnnotationTransactionAttributeSource
    @Bean
    @Role(2)
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }
    
    // 向Spring容器中注册TransactionInterceptor
    @Bean
    @Role(2)
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }

        return interceptor;
    }
}
  • AnnotationTransactionAttributeSource

完成创建SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser对象并添加到解析器列表中,以便后面处理对应注解的工作。其中SpringTransactionAnnotationParser负责对注解org.springframework.transaction.annotation.Transactional进行解析,JtaTransactionAnnotationParser负责javax.transaction.Transactional,Ejb3TransactionAnnotationParser负责javax.ejb.TransactionAttribute。这些解析器会根据注解的内容,将其封装成TransactionAttributeSource对象。

  • TransactionInterceptor

主要完成创建事务,调用实际方法,完成事务的提交或回滚操作的统一处理。

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable

MethodInterceptor是Spring AOP中主要完成通知功能的,可以将其理解成动态代理中的handler(比如JDK动态代理中的InvocationHandler,CGLIB动态代理中的Callback),只不过Spring为了更好的适用于AOP而做了处理。TransactionInterceptor 重写了Invoke方法,当调用代理对象的方法时,在代理对象方法内部对调用TransactionInterceptor的invoke方法完成后续的工作:

public Object invoke(final MethodInvocation invocation) throws Throwable {
    Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
    return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
    });
}

invokeWithinTransaction的方法时继承自TransactionAspectSupport。TransactionAspectSupport是个模板类,完成了主要的代理工作逻辑。

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean
// 实现事务处理的主要方法
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
    // 获取方法上@Transactional注解中的内容,TransactionAttribute是解析器解析注解配置封装的对象
    final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    // 获取事务管理器
    final PlatformTransactionManager tm = this.determineTransactionManager(txAttr);
    final String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
    // 如果事务管理器是CallbackPreferringPlatformTransactionManager类型的,应该是异步调用
    if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) {
        try {
            Object result = ((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr, new TransactionCallback<Object>() {
                public Object doInTransaction(TransactionStatus status) {
                    // 开启事务,start transaction,Spring将事务使用了ThreadLocal保存,即一个线程对应一个自己的事务
                    TransactionAspectSupport.TransactionInfo txInfo = TransactionAspectSupport.this.prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

                    TransactionAspectSupport.ThrowableHolder var4;
                    try {
                        // 完成实际对象方法的调用
                        Object var3 = invocation.proceedWithInvocation();
                        return var3;
                    } catch (Throwable var8) {
                        // 方法抛出异常就回滚事务
                        if (txAttr.rollbackOn(var8)) {
                            if (var8 instanceof RuntimeException) {
                                throw (RuntimeException)var8;
                            }

                            throw new TransactionAspectSupport.ThrowableHolderException(var8);
                        }

                        var4 = new TransactionAspectSupport.ThrowableHolder(var8);
                    } finally {
                        // 移除线程中的ThreadLocal内容
                        TransactionAspectSupport.this.cleanupTransactionInfo(txInfo);
                    }

                    return var4;
                }
            });
            if (result instanceof TransactionAspectSupport.ThrowableHolder) {
                throw ((TransactionAspectSupport.ThrowableHolder)result).getThrowable();
            } else {
                return result;
            }
        } catch (TransactionAspectSupport.ThrowableHolderException var14) {
            throw var14.getCause();
        }
    } else {// 同步调用
        // 开启事务,即start transaction
        TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        Object retVal = null;

        try {
            // 调用实际对象方法
            retVal = invocation.proceedWithInvocation();
        } catch (Throwable var15) {
            // 方法抛出异常,根据@Transactional注解配置的rollbackFor等内容和实际的异常类型,完成事务的提交或回滚
            this.completeTransactionAfterThrowing(txInfo, var15);
            throw var15;
        } finally {
            this.cleanupTransactionInfo(txInfo);
        }
        // 提交事务
        this.commitTransactionAfterReturning(txInfo);
        return retVal;
    }
}

上面的内容有两个地方需要看看,一个是如何根据@Transactional的配置创建事务的,即createTransactionIfNecessary方法或prepareTransactionInfo方法。另一个是实际对象方法的调用,即invocation.proceedWithInvocation()

// 创建事务
protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
    if (txAttr != null && ((TransactionAttribute)txAttr).getName() == null) {
        txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) {
            public String getName() {
                return joinpointIdentification;
            }
        };
    }

    TransactionStatus status = null;
    if (txAttr != null) {
        if (tm != null) {
            // 调用事务管理器的getTransaction,根据注解配置的隔离级别,传播机制
            status = tm.getTransaction((TransactionDefinition)txAttr);
        } else if (this.logger.isDebugEnabled()) {
            this.logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured");
        }
    }

    return this.prepareTransactionInfo(tm, (TransactionAttribute)txAttr, joinpointIdentification, status);
}

protected TransactionAspectSupport.TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm, TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {
    TransactionAspectSupport.TransactionInfo txInfo = new TransactionAspectSupport.TransactionInfo(tm, txAttr, joinpointIdentification);
    if (txAttr != null) {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
        }
        // 设置TransactionStatus
        txInfo.newTransactionStatus(status);
    } else if (this.logger.isTraceEnabled()) {
        this.logger.trace("Don't need to create transaction for [" + joinpointIdentification + "]: This method isn't transactional.");
    }
    // 将创建的事务,即TransactionInfo对象通过TreadLocal绑定到线程上
    txInfo.bindToThread();
    return txInfo;
}

proceedWithInvocation方法是一个接口中的方法,具体要看子类的实现。查看子类的实现,要回到TransactionInterceptor的Invoke方法:

public Object invoke(final MethodInvocation invocation) throws Throwable {
    Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
    return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
        public Object proceedWithInvocation() throws Throwable {
            // 调用invocation.proceedWithInvocation(),实际会转发到invocation.proceed()方法中
            return invocation.proceed();
        }
    });
}

invocation实际上是CglibMethodInvocation,调用invocation.proceed()就是调用CglibMethodInvocation.proceed(),此方法是继承自父类ReflectiveMethodInvocation:

public Object proceed() throws Throwable {
    // 判断是否是interceptorsAndDynamicMethodMatchers中的最后一个通知逻辑
    // interceptorsAndDynamicMethodMatchers存放着方法对应的多个通知。
    // currentInterceptorIndex初始值是-1,若interceptorsAndDynamicMethodMatchers中有元素的话,这里的if逻辑第一次进行是为false的
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        // 调用实际方法去
        return this.invokeJoinpoint();
    } else {
        // 获取通知
        Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        // 如果通知类型是InterceptorAndDynamicMethodMatcher
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
            // 如果方法匹配。执行对应通知的invoke方法,这里会回到TransactionInterceptor的invoke方法,否则再次进行当前方法,
            // 获取interceptorsAndDynamicMethodMatchers列表中下一个通知,重复上面的逻辑。
            return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
        } else {
            // 继续执行通知的invoke方法,然后还会回到当前方法
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}
  • BeanFactoryTransactionAttributeSourceAdvisor

创建BeanFactoryTransactionAttributeSourceAdvisor对象,并添加到Spring容器中,后面的功能就交给Spring AOP去处理了。


█ 传播机制

传播机制是通过事务管理器获取事务的时候会被使用到。

tm.getTransaction((TransactionDefinition)txAttr);

然后进到事务管理器类AbstractPlatformTransactionManager中:

public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
    Object transaction = this.doGetTransaction();
    boolean debugEnabled = this.logger.isDebugEnabled();
    if (definition == null) {
        definition = new DefaultTransactionDefinition();
    }
    if (this.isExistingTransaction(transaction)) {
        // 进到这里的方法
        return this.handleExistingTransaction((TransactionDefinition)definition, transaction, debugEnabled);
    } else if (((TransactionDefinition)definition).getTimeout() < -1) {
        throw new InvalidTimeoutException("Invalid transaction timeout", ((TransactionDefinition)definition).getTimeout());
    } else if (((TransactionDefinition)definition).getPropagationBehavior() == 2) {
        throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
    } else if (((TransactionDefinition)definition).getPropagationBehavior() != 0 && ((TransactionDefinition)definition).getPropagationBehavior() != 3 && ((TransactionDefinition)definition).getPropagationBehavior() != 6) {
        if (((TransactionDefinition)definition).getIsolationLevel() != -1 && this.logger.isWarnEnabled()) {
            this.logger.warn("Custom isolation level specified but no actual transaction initiated; isolation level will effectively be ignored: " + definition);
        }

        boolean newSynchronization = this.getTransactionSynchronization() == 0;
        return this.prepareTransactionStatus((TransactionDefinition)definition, (Object)null, true, newSynchronization, debugEnabled, (Object)null);
    } else {
        AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources = this.suspend((Object)null);
        if (debugEnabled) {
            this.logger.debug("Creating new transaction with name [" + ((TransactionDefinition)definition).getName() + "]: " + definition);
        }

        try {
            boolean newSynchronization = this.getTransactionSynchronization() != 2;
            DefaultTransactionStatus status = this.newTransactionStatus((TransactionDefinition)definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            this.doBegin(transaction, (TransactionDefinition)definition);
            this.prepareSynchronization(status, (TransactionDefinition)definition);
            return status;
        } catch (RuntimeException var7) {
            this.resume((Object)null, suspendedResources);
            throw var7;
        } catch (Error var8) {
            this.resume((Object)null, suspendedResources);
            throw var8;
        }
    }
}
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException {
    if (definition.getPropagationBehavior() == 5) {
        throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'");
    } else {
        AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources;
        boolean newSynchronization;
        if (definition.getPropagationBehavior() == 4) {
            if (debugEnabled) {
                this.logger.debug("Suspending current transaction");
            }

            suspendedResources = this.suspend(transaction);
            newSynchronization = this.getTransactionSynchronization() == 0;
            return this.prepareTransactionStatus(definition, (Object)null, false, newSynchronization, debugEnabled, suspendedResources);
        } else if (definition.getPropagationBehavior() == 3) {
            if (debugEnabled) {
                this.logger.debug("Suspending current transaction, creating new transaction with name [" + definition.getName() + "]");
            }

            suspendedResources = this.suspend(transaction);

            try {
                newSynchronization = this.getTransactionSynchronization() != 2;
                DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
                this.doBegin(transaction, definition);
                this.prepareSynchronization(status, definition);
                return status;
            } catch (RuntimeException var7) {
                this.resumeAfterBeginException(transaction, suspendedResources, var7);
                throw var7;
            } catch (Error var8) {
                this.resumeAfterBeginException(transaction, suspendedResources, var8);
                throw var8;
            }
        } else {
            boolean newSynchronization;
            if (definition.getPropagationBehavior() == 6) {
                if (!this.isNestedTransactionAllowed()) {
                    throw new NestedTransactionNotSupportedException("Transaction manager does not allow nested transactions by default - specify 'nestedTransactionAllowed' property with value 'true'");
                } else {
                    if (debugEnabled) {
                        this.logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
                    }

                    if (this.useSavepointForNestedTransaction()) {
                        DefaultTransactionStatus status = this.prepareTransactionStatus(definition, transaction, false, false, debugEnabled, (Object)null);
                        status.createAndHoldSavepoint();
                        return status;
                    } else {
                        newSynchronization = this.getTransactionSynchronization() != 2;
                        DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, (Object)null);
                        this.doBegin(transaction, definition);
                        this.prepareSynchronization(status, definition);
                        return status;
                    }
                }
            } else {
                if (debugEnabled) {
                    this.logger.debug("Participating in existing transaction");
                }

                if (this.isValidateExistingTransaction()) {
                    if (definition.getIsolationLevel() != -1) {
                        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, "ISOLATION_") : "(unknown)"));
                        }
                    }

                    if (!definition.isReadOnly() && TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                        throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is");
                    }
                }

                newSynchronization = this.getTransactionSynchronization() != 2;
                return this.prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, (Object)null);
            }
        }
    }
}

欢迎评论指导,留下您宝贵的建议或意见,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值