Spring源码解析系列(8)之事务底层原理

开启事务的注解

@EnableTransactionManagement

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TransactionManagementConfigurationSelector.class}) // 导入了此类
public @interface EnableTransactionManagement {
    boolean proxyTargetClass() default false;
​
    AdviceMode mode() default AdviceMode.PROXY;
​
    int order() default 2147483647;
}

TransactionManagementConfigurationSelector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    public TransactionManagementConfigurationSelector() {
    }
​
    protected String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
        case PROXY: // 默认是此模式
                // 导入AutoProxyRegistrar和ProxyTransactionManagementConfiguration
                // AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,所以在递归处理的时候也会发现其实现了ImportBeanDefinitionRegistrar接口,将其添加到集合中,后续进行统一的处理,调用他的import方法,这个import方法内部就是想要注册InfrastructureAdvisorAutoProxyCreator后置处理器来开启事务,如果原来已经开启了事务,就会比较他们的优先级,默认后来的优先级是0,已经配置的优先级是2,所以后来的优先级更高,会替换原来的AnnotationAwareAspectJAutoProxyCreator,当然这也要看注解的排列数序,反正后来的会替换原来的。
            return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
        case ASPECTJ:
            return new String[]{this.determineTransactionAspectClass()};
        default:
            return null;
        }
    }
​
    private String determineTransactionAspectClass() {
        return ClassUtils.isPresent("javax.transaction.Transactional", this.getClass().getClassLoader()) ? "org.springframework.transaction.aspectj.AspectJJtaTransactionManagementConfiguration" : "org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";
    }
}

ProxyTransactionManagementConfiguration是一个配置类

因为使用Import导入时,发现实现了ImportSelector接口,会对方法中导入的类递归执行process()方法,所以此配置类也将会被处理,

在此类中就是向容器中导入了三个类,分别是Advisor,pointcut,Advise,实际上pointcut,Advise都被封装在了导入的增强器 BeanFactoryTransactionAttributeSourceAdvisor 中

@Configuration(
    proxyBeanMethods = false
)
@Role(2)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    public ProxyTransactionManagementConfiguration() {
    }
​
    @Bean(
        name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
    )
    @Role(2)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
        // 创建了一个advisor增强器
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        // 设置增强器中的pointcut
        advisor.setTransactionAttributeSource(transactionAttributeSource);
        // 设置增强器中的advise
        advisor.setAdvice(transactionInterceptor);
        if (this.enableTx != null) {
            advisor.setOrder((Integer)this.enableTx.getNumber("order"));
        }
​
        return advisor;
    }
​
    @Bean
    @Role(2)
    public TransactionAttributeSource transactionAttributeSource() {
        // 相当于pointcut--获取切面的,
       // 我们通常的Advisor中,都包含pointcut,我们会利用pointcut的match()方法,判断bean是否有相匹配的增强器,在事务的Advisor中,是通过AnnotationTransactionAttributeSource的getTransactionAttribute方法判断该pointcut所在的增强器,是否与当前bean相匹配(会先从类上面找是否有@Transaction注解,再从方法上找是否有@Transaction注解)
        return new AnnotationTransactionAttributeSource();
    }
​
    @Bean
    @Role(2)
    public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
        // 相当于advise--增强的具体逻辑
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(transactionAttributeSource);
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }
​
        return interceptor;
    }
}

BeanFactoryTransactionAttributeSourceAdvisor: 事务的增强器

Pointcut(判断是否可以作用于当前方法)Advice(作用于当前方法的具体逻辑)

BeanFactoryTransactionAttributeSourceAdvisor

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
    @Nullable
    // 保存事务的属性信息
    private TransactionAttributeSource transactionAttributeSource;
    // 事务属性源pointcut,调用其matchs()方法,判断其所在的增强器,能否与当前bean相匹配,但是matchs()它内部实际上,是调用了transactionAttributeSource的getTransactionAttribute()方法进行匹配的。
   
    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            // 获取该pointcut所对应的事务属性源
            return BeanFactoryTransactionAttributeSourceAdvisor.this.transactionAttributeSource;
        }
    };
​
    public BeanFactoryTransactionAttributeSourceAdvisor() {
    }
​
    public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
        this.transactionAttributeSource = transactionAttributeSource;
    }
​
    public void setClassFilter(ClassFilter classFilter) {
        this.pointcut.setClassFilter(classFilter);
    }
​
    public Pointcut getPointcut() {
        return this.pointcut;
    }
}
​
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
    public boolean matches(Method method, Class<?> targetClass) {
        TransactionAttributeSource tas = this.getTransactionAttributeSource();
        // 实际上调用了tas的getTransactionAttribute方法,实际上AnnotationTransactionAttributeSource没有实现getTransactionAttribute()方法,调用的是他父类AbstractFallbackTransactionAttributeSource的
        return tas == null || tas.getTransactionAttribute(method, targetClass) != null;
    }
}

AbstractFallbackTransactionAttributeSource#getTransactionAttribute()

/**
     * 针对没有事务注解属性的方法进行事务注解属性缓存时使用的特殊值,用于标记该方法没有事务注解属性,
     * 从而不用在首次缓存在信息后,不用再次重复执行真正的分析
     **/
    private static final TransactionAttribute NULL_TRANSACTION_ATTRIBUTE = new DefaultTransactionAttribute() {
        public String toString() {
            return "null";
        }
    };
​
// 缓存方法上面的事务属性
 private final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap(1024);
​
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // 如果该方法所在的类是Object类,直接返回null,不开启事务
    if (method.getDeclaringClass() == Object.class) {
        return null;
    } else {
        // 创建缓存键对象(对当前方法和目标类进行的封装)
        Object cacheKey = this.getCacheKey(method, targetClass);
        // 从注解缓存中获取当前方法的事务注解属性
        TransactionAttribute cached = (TransactionAttribute)this.attributeCache.get(cacheKey);
        // 如果获取到了缓存键对应的注解属性,证明已经解析过(但是不能判断是否事务注解属性真的存在,因为就算没有注解属性,也会缓存起来,这里只缓存起到的作用:1.标记已经解析过了 2.保存方法注解属性)
        if (cached != null) {
            // 如果解析过了,但是没有注解属性返回null,否则将注解属性返回
            return cached == NULL_TRANSACTION_ATTRIBUTE ? null : cached;
        } else {
            // 缓存中没有注解属性,就去解析
            /**
                解析原则:
                先获取目标类(如果有接口,就是接口的实现类)上的该method(因为如果目标类有实现接口,那么此方法也就是指接口上的method),所以我们需要获取真正目标类真正重写的方法(specificMethod ),
                1.先解析specificMethod方法上是否有事务属性,如果有直接返回,如果没有↓
                2.判断specificMethod所在的目标类上是否有事务属性,如果有直接返回,如果没有👇
                3.判断method和specificMethod是否相同,也就是specificMethod方法是不是重写了父类或者父接口的方法
                4.如果不相同,证明重写了方法:
                    4.1尝试从method上获取事务注解属性,如果存在直接返回
                    4.2如果不存在,就从method所在的类(父类或者接口)上获取事务注解,如果有直接返回,如果没有就返回null
            **/
            TransactionAttribute txAttr = this.computeTransactionAttribute(method, targetClass);
            // 如果解析后,注解属性为null,将其缓存起来,证明已经解析过了,并标记为没有注解属性(NULL_TRANSACTION_ATTRIBUTE)
            if (txAttr == null) {
                // 放入缓存中
                this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
            } else {
                // 最后获取到了注解属性,也会将缓存键和注解属性放入缓存
                String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
                if (txAttr instanceof DefaultTransactionAttribute) {
                    DefaultTransactionAttribute dta = (DefaultTransactionAttribute)txAttr;
                    dta.setDescriptor(methodIdentification);
                    dta.resolveAttributeStrings(this.embeddedValueResolver);
                }
​
                if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
                }
​
                this.attributeCache.put(cacheKey, txAttr);
            }
// 返回注解属性
            return txAttr;
        }
    }
}

computeTransactionAttribute()

@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // 如果事务注解属性分析仅仅针对public方法,而当前方法不是public,则直接返回null
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }
​
    // 参数 method 可能是基于接口的方法,该接口和参数targetClass所对应的类不同(也就是说:
    // targetClass是相应接口的某个实现类),而我们这里需要的属性是要来自targetClass的,
    // 所以这里先获取targetClass上的那个和method对应的方法,这里 method, specificMethod 
    // 都可以认为是潜在的目标方法
    Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
​
    // 首先尝试检查事务注解属性直接标记在目标方法 specificMethod 上
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
        // 事务注解属性直接标记在目标方法上
        return txAttr;
    }
​
    // 然后尝试检查事务注解属性是否标记在目标方法 specificMethod 所属类上
    txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
    if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
        // 事务注解属性是否标记在目标方法所属类上
        return txAttr;
    }
    
    // 逻辑走到这里说明目标方法specificMethod,也就是实现类上的目标方法上没有标记事务注解属性
    if (specificMethod != method) {
        // 如果 specificMethod 和 method 不同,则说明 specificMethod 是具体实现类
        // 的方法,method 是实现类所实现接口的方法,现在尝试从 method 上获取事务注解属性
        txAttr = findTransactionAttribute(method);
        if (txAttr != null) {
            return txAttr;
        }
        // 现在尝试在 method 所属类上查看是否有事务注解属性
        txAttr = findTransactionAttribute(method.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }
    }
    // specificMethod 方法/所属类上没有事务注解属性,
    // method 方法/所属类上也没有事务注解属性,
    // 所以返回 null
    return null;
}

看一下,开启事务之后,我们在通过getType(Advisor.class)第一次获取增强器时就可以拿到,配置类中注册的增强器了,接下来就正常生成代理对象

那么我们只需要关注TransactionInterceptor拦截器中的拦截逻辑就可以了:

invoke

@Nullable
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 CoroutinesInvocationCallback() {
        @Nullable
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
​
        public Object getTarget() {
            return invocation.getThis();
        }
​
        public Object[] getArguments() {
            return invocation.getArguments();
        }
    });
}

在分析此方法之前,我们先来看一下,针对于事务Spring提供的三大接口:

PlatformTransactionManager:平台事务管理器,用来管理事务

TransactionDefinition:事务的定义信息(事务的隔离级别、事务的传播行为、超时、只读、回滚规则)

TransactionStatus:事务的运行状态

PlatformTransactionManager

package org.springframework.transaction;
import org.springframework.lang.Nullable;
​
public interface PlatformTransactionManager extends TransactionManager {
​
    /** 
    *   获取事物状态 
    */
    TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
            throws TransactionException;
    
    /** 
    *   事物提交 
    */
    void commit(TransactionStatus status) throws TransactionException;
    
    /** 
    *   事物回滚 
    */
    void rollback(TransactionStatus status) throws TransactionException;
​
}

TransactionDefinition:

package org.springframework.transaction;
import org.springframework.lang.Nullable;
​
​
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;
    
    /**
     * 表示如果当前正有一个事务在运行中,则该方法应该运行在 一个嵌套的事务中, 
     * 被嵌套的事务可以独立于封装事务进行提交或者回滚(保存点),
     * 如果封装事务不存在,行为就像 PROPAGATION_REQUIRES NEW
     */
    int PROPAGATION_NESTED = 6;
​
​
    /**
     * 使用后端数据库默认的隔离级别,
     * Mysql 默认采用的 REPEATABLE_READ隔离级别 
     * Oracle 默认采用的 READ_COMMITTED隔离级别
     */
    int ISOLATION_DEFAULT = -1;
    
    /**
     * 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
     */
    int ISOLATION_READ_UNCOMMITTED = 1;  
    // same as java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
    
    /**
     * 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
     */
    int ISOLATION_READ_COMMITTED = 2;  
    // same as java.sql.Connection.TRANSACTION_READ_COMMITTED;
    
    /**
     * 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,
     * 可以阻止脏读和不可重复读,但幻读仍有可能发生
     */
    int ISOLATION_REPEATABLE_READ = 4;  
    // same as java.sql.Connection.TRANSACTION_REPEATABLE_READ;
    
    /**
     * 最高的隔离级别,完全服从ACID的隔离级别。
     * 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰, 
     * 也就是说,该级别可以防止脏读、不可重复读以及幻读。
     * 但是这将严重影响程序的性能通常情况下也不会用到该级别
     */
    int ISOLATION_SERIALIZABLE = 8;  
    // same as java.sql.Connection.TRANSACTION_SERIALIZABLE;
​
​
    /**
     * 使用默认的超时时间
     */
    int TIMEOUT_DEFAULT = -1;
​
​
    /**
     * 获取事物的传播行为
     */
    default int getPropagationBehavior() {
        return PROPAGATION_REQUIRED;
    }
    
    /**
     * 获取事物的隔离级别
     */
    default int getIsolationLevel() {
        return ISOLATION_DEFAULT;
    }
    
    /**
     * 返回事物的超时时间
     */
    default int getTimeout() {
        return TIMEOUT_DEFAULT;
    }
    
    /**
     * 返回当前是否为只读事物
     */
    default boolean isReadOnly() {
        return false;
    }
    
    /**
     * 获取事物的名称
     */
    @Nullable
    default String getName() {
        return null;
    }
​
}

TransactionStatus

TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信 息. PlatformTransactionManager.getTransaction(…) 方法返回一个 TransactionStatus 对象。返回的 TransactionStatus 对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的 事物

package org.springframework.transaction;
import java.io.Flushable;
​
​
public interface TransactionStatus extends SavepointManager, Flushable {
​
    /**
     * 是否为新事物
     */
    boolean isNewTransaction();
    
    /**
     * 是否有保存点
     */
    boolean hasSavepoint();
    
    /**
     * 设置为只回滚
     */
    void setRollbackOnly();
    
    /**
     * 是否为只回滚
     */
    boolean isRollbackOnly();
    
    /**
     * 属性
     */
    @Override
    void flush();
    
    /**
     * 判断当前事物是否已经完成
     */
    boolean isCompleted();
​
}

invokeWithinTransaction

了解一下:

在还没有加入响应式/反应式事务集成之间,Spring认为没有必须进行Reactive事务管理,因此,Spring Framework不支持Reactive @Transaction。

随着时间的推移,MongoDB开始支持MongoDB Server 4.0的多文档事务,R2DBC(反应式SQL数据库驱动程序的规范)开始出现,最终在Template API中提供inTransaction(…) 方法作为执行原生本级事务的工作单元。

虽然将inTransaction(…)方法用于较小的工作块很方便,但它并不反映Spring支持事务的方式。在使用命令式编程模型时,Spring Framework允许两种事务管理安排:@Transactional和TransactionTemplate(声明性的各自的程序化事务管理)。

这两种事务管理方法都建立在PlatformTransactionManager管理事务资源事务的基础之上。PlatformTransactionManager可以是Spring提供的事务管理器实现,也可以是基于JTA的Java EE实现。

两种方法的共同之处在于它们将事务状态绑定到ThreadLocal存储,这允许事务状态管理而不传递TransactionStatus对象。事务管理应该在后台以非侵入方式进行。因为我们没有让线程继续在事务中继续有作用工作的设想,因此ThreadLocal只在命令式编程中工作。

看一下事务管理器的继承关系图:

@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
    // 获取我们之前通过开启事务导入的配置类中注册的的TransactionAttributeSource,也就pointcut,
    TransactionAttributeSource tas = this.getTransactionAttributeSource();
    // 获取指定方法上的事务注解属性
    TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
    // 决策(选择)一个合适的事务管理器-->会获取我们自己注册的事务管理器(该管理器会被放入事务管理器缓存中)--->如果我们自己没有配置事务管理器,会报错
    TransactionManager tm = this.determineTransactionManager(txAttr);
    // 对不同事务情景的处理
    // ====================对于反应式事务的处理================ 
    if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
        boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
        boolean hasSuspendingFlowReturnType = isSuspendingFunction && "kotlinx.coroutines.flow.Flow".equals((new MethodParameter(method, -1)).getParameterType().getName());
        if (isSuspendingFunction && !(invocation instanceof TransactionAspectSupport.CoroutinesInvocationCallback)) {
            throw new IllegalStateException("Coroutines invocation not supported: " + method);
        } else {
            TransactionAspectSupport.CoroutinesInvocationCallback corInv = isSuspendingFunction ? (TransactionAspectSupport.CoroutinesInvocationCallback)invocation : null;
            TransactionAspectSupport.ReactiveTransactionSupport txSupport = (TransactionAspectSupport.ReactiveTransactionSupport)this.transactionSupportCache.computeIfAbsent(method, (key) -> {
                Class<?> reactiveType = isSuspendingFunction ? (hasSuspendingFlowReturnType ? Flux.class : Mono.class) : method.getReturnType();
                ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
                if (adapter == null) {
                    throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " + method.getReturnType());
                } else {
                    return new TransactionAspectSupport.ReactiveTransactionSupport(adapter);
                }
            });
            TransactionAspectSupport.InvocationCallback callback = invocation;
            if (corInv != null) {
                callback = () -> {
                    return CoroutinesUtils.invokeSuspendingFunction(method, corInv.getTarget(), corInv.getArguments());
                };
            }
​
            Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, (ReactiveTransactionManager)tm);
            if (corInv != null) {
                Publisher<?> pr = (Publisher)result;
                return hasSuspendingFlowReturnType ? TransactionAspectSupport.KotlinDelegate.asFlow(pr) : TransactionAspectSupport.KotlinDelegate.awaitSingleOrNull(pr, corInv.getContinuation());
            } else {
                return result;
            }
        }
    } else {
    // =========对于非反应式事务的处理(声明式和编程式)===
        /**
       声明式和编程式的事务管理器都实现了PlatformTransactionManager接口
        **/
        // 将事务管理器转化为PlatformTransactionManager类型
        PlatformTransactionManager ptm = this.asPlatformTransactionManager(tm);
     // 获取连接点描述(需要被增强的方法的路径的字符串形式)
        String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
    // ====================对于编程式事务的处理==================
        if (txAttr != null && ptm instanceof CallbackPreferringPlatformTransactionManager) {
            TransactionAspectSupport.ThrowableHolder throwableHolder = new TransactionAspectSupport.ThrowableHolder();
​
            Object result;
            try {
                result = ((CallbackPreferringPlatformTransactionManager)ptm).execute(txAttr, (statusx) -> {
                    TransactionAspectSupport.TransactionInfo txInfo = this.prepareTransactionInfo(ptm, txAttr, joinpointIdentification, statusx);
​
                    Object var9;
                    try {
                        Object retVal = invocation.proceedWithInvocation();
                        if (retVal != null && vavrPresent && TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {
                            retVal = TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, statusx);
                        }
​
                        var9 = retVal;
                        return var9;
                    } catch (Throwable var13) {
                        if (txAttr.rollbackOn(var13)) {
                            if (var13 instanceof RuntimeException) {
                                throw (RuntimeException)var13;
                            }
​
                            throw new TransactionAspectSupport.ThrowableHolderException(var13);
                        }
​
                        throwableHolder.throwable = var13;
                        var9 = null;
                    } finally {
                        this.cleanupTransactionInfo(txInfo);
                    }
​
                    return var9;
                });
            } catch (TransactionAspectSupport.ThrowableHolderException var22) {
                throw var22.getCause();
            } catch (TransactionSystemException var23) {
                if (throwableHolder.throwable != null) {
                    this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                    var23.initApplicationException(throwableHolder.throwable);
                }
​
                throw var23;
            } catch (Throwable var24) {
                if (throwableHolder.throwable != null) {
                    this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                }
​
                throw var24;
            }
​
            if (throwableHolder.throwable != null) {
                throw throwableHolder.throwable;
            } else {
                return result;
            }
        } else {
    // ===================对于编程式事务的处理=============
    // 如果需要话就创建事务的信息,并在创建好事务信息之后,将其放入了ThreadLocal中,在内部事务,连接都创建完成了,封装到了transactionStatus中,transactionStatus又会被封装到TransactionInfo中
            TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
​
            Object retVal;
            try {
           // 执行添加了事务之后的方法(如果开启事务的方法上也有其他增强器比如@Before。@After等,会递归进行调用的)
                retVal = invocation.proceedWithInvocation();
            } catch (Throwable var20) {
                // 7. 异常回滚
                this.completeTransactionAfterThrowing(txInfo, var20);
                throw var20;
            } finally {
                // 8. 提交之前清除事务信息
                this.cleanupTransactionInfo(txInfo);
            }
​
            if (retVal != null && vavrPresent && TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {
                TransactionStatus status = txInfo.getTransactionStatus();
                if (status != null && txAttr != null) {
                    retVal = TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
                }
            }
            // 9.提交事务
            this.commitTransactionAfterReturning(txInfo);
            return retVal;
        }
    }
}

看一下,事务属性中的内容:

看一下连接点的描述:

createTransactionIfNecessary

protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm, @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
    if (txAttr != null && ((TransactionAttribute)txAttr).getName() == null) {
        // 将当前获取到的transactionAttribute包装在DelegatingTransactionAttribute内部,它是TransactionAttribute接口的一个实现类
        txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) {
            public String getName() {
           // 返回连接点方法的描述(路径字符串)
                return joinpointIdentification;
            }
        };
    }
​
    TransactionStatus status = null;
    if (txAttr != null) {
        if (tm != null) {
       // 创建事务状态对象,这步是关键步骤,下面分析
            status = tm.getTransaction((TransactionDefinition)txAttr);
        } else if (this.logger.isDebugEnabled()) {
            this.logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured");
        }
    }
    // 将事务属性,连接点描述,事务状态,事务管理器封装成事务信息info
    return this.prepareTransactionInfo(tm, (TransactionAttribute)txAttr, joinpointIdentification, status);
}

getTransaction

先看一下,TransactionAttribute的继承关系图

要知道我们的连接保存在JdbcTransactionObjectSupport类中,DataSourceTransactionObjectDataSourceTransactionManager的内部类,DataSourceTransactionObject继承了JdbcTransactionObjectSupport

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
    // 将TransactionAttribute统一成TransactionDefinition类型
    TransactionDefinition def = definition != null ? definition : TransactionDefinition.withDefaults();
    // 获取事务对象**DataSourceTransactionObject**,其中保存着连接connection
    // doGetTransaction()是AbstractPlatformTransactionManager中的抽象方法,该抽象类实现了PlatformTransactionManager接口
    // 针对于不同的事务管理器,doGetTransaction()有不同的实现
    Object transaction = this.doGetTransaction();
    boolean debugEnabled = this.logger.isDebugEnabled();
  // 判断是否存在事务
    if (this.isExistingTransaction(transaction)) {
        return this.handleExistingTransaction(def, transaction, debugEnabled);
        // 判断是否超时
    } else if (def.getTimeout() < -1) {
        throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
        // 判断事务传播行为是不是2(PROPAGATION_MANDATORY),该传播行为在没有事务时,会抛出异常
    } else if (def.getPropagationBehavior() == 2) {
        throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
        /** 
        int PROPAGATION_REQUIRED = 0;支持当前事物,若当前没有事物就创建一个事物,有事务就用原事务
        int PROPAGATION_REQUIRES_NEW = 3;创建一个新的事务,如果当前存在事务,则把当前事务挂起;不存在,就创建
        int PROPAGATION_NESTED = 6;表示如果当前正有一个事务在运行中,    则该方法应该运行在 一个嵌套的事务中,  被嵌套的事务可以独立于封装事务进行提交或者回滚(保存点), 如果封装事务不存在,行为就像 PROPAGATION_REQUIRES NEW
        **/
        // 以上都是需要创建事务的情况,该else if判断内部都是不需要创建事务,以非事务运行的情况
    } else if (def.getPropagationBehavior() != 0 && def.getPropagationBehavior() != 3 && def.getPropagationBehavior() != 6) {
        // 隔离级别=-1:表示使用数据库默认的隔离级别
        if (def.getIsolationLevel() != -1 && this.logger.isWarnEnabled()) {
            this.logger.warn("Custom isolation level specified but no actual transaction initiated; isolation level will effectively be ignored: " + def);
        }
​
        boolean newSynchronization = this.getTransactionSynchronization() == 0;
        return this.prepareTransactionStatus(def, (Object)null, true, newSynchronization, debugEnabled, (Object)null);
    } else {
 // 到这里是真正需要创建事务的情况了 ,此处第一次进来会返回null     
        AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources = this.suspend((Object)null);
        if (debugEnabled) {
            this.logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
        }
​
        try {
            // 开始获取事务,很重要,到这里才正式创建
            return this.startTransaction(def, transaction, debugEnabled, suspendedResources);
        } catch (Error | RuntimeException var7) {
            this.resume((Object)null, suspendedResources);
            throw var7;
        }
    }
}
​
​
//doGetTransaction()获取事务对象
    protected Object doGetTransaction() {
  // 创建DataSourceTransactionObject对象,它是事务管理器的一个内部类,同时它是连接的持有者
        DataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject();
 // 设置是否允许使用保存点,默认允许      
        txObject.setSavepointAllowed(this.isNestedTransactionAllowed());
    // 创建连接的持有对象(获取数据源,获取ThreadLocal中dataSource对应的连接对象),首次获取肯定获取不到,为null
        ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.obtainDataSource());
        // 设置连接连接对象
        txObject.setConnectionHolder(conHolder, false);
        return txObject;
    }
​
    public static Object getResource(Object key) {
        // 此处就拿到了数据源对象
        Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
        // 去ThreadLocal中获取线程对应的连接
        return doGetResource(actualKey);
    }
​
​
    private static Object doGetResource(Object actualKey) {
        // private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal("Transactional resources");
        // 从ThreadLocal中获取连接对象
        Map<Object, Object> map = (Map)resources.get();
        if (map == null) {
       // 获取不到返回null
            return null;
        } else {
            Object value = map.get(actualKey);
            if (value instanceof ResourceHolder && ((ResourceHolder)value).isVoid()) {
                map.remove(actualKey);
                if (map.isEmpty()) {
                    resources.remove();
                }
​
                value = null;
            }
​
            return value;
        }
    }

isExistingTransaction

protected boolean isExistingTransaction(Object transaction) {
    DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
    // 判断事务对象中是否存在连接,如果存在连接,看看该链接中的事务是不是活跃的(正在使用)
    return txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive();
}

suspend()

@Nullable
protected final AbstractPlatformTransactionManager.SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
    // 去    private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal("Transaction synchronizations");中拿,默认拿不到
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        List suspendedSynchronizations = this.doSuspendSynchronization();
​
        try {
            Object suspendedResources = null;
            if (transaction != null) {
                suspendedResources = this.doSuspend(transaction);
            }
​
            String name = TransactionSynchronizationManager.getCurrentTransactionName();
            TransactionSynchronizationManager.setCurrentTransactionName((String)null);
            boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
            TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
            Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            TransactionSynchronizationManager.setCurrentTransactionIsolationLevel((Integer)null);
            boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
            TransactionSynchronizationManager.setActualTransactionActive(false);
            return new AbstractPlatformTransactionManager.SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
        } catch (Error | RuntimeException var8) {
            this.doResumeSynchronization(suspendedSynchronizations);
            throw var8;
        }
        // 默认传入的transaction=null
    } else if (transaction != null) {
        Object suspendedResources = this.doSuspend(transaction);
        return new AbstractPlatformTransactionManager.SuspendedResourcesHolder(suspendedResources);
    } else {
        return null;
    }
}

startTransaction()

private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled, @Nullable AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources) {
    boolean newSynchronization = this.getTransactionSynchronization() != 2;
    DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    // 此处才开始创建连接,并将事务对象(连接的持有者)封装到了事务状态中
    this.doBegin(transaction, definition);
    this.prepareSynchronization(status, definition);
    // 返回事务状态
    return status;
}

this.doBegin(transaction, definition)

protected void doBegin(Object transaction, TransactionDefinition definition) {
    // 获取DataSourceTransactionObject,前面提到过,它会持有链接
    DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
    Connection con = null;
​
    try {
        if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
           // 利用数据源创建连接
            Connection newCon = this.obtainDataSource().getConnection();
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
            }
    // 设置连接conn到DataSourceTransactionObject 中的连接持有者属性ConnectionHolder里,并将是否为新的连接设置为true
            txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
        }
// 设置同步事务为true
        txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
        con = txObject.getConnectionHolder().getConnection();
        Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
 // 设置隔离界别      
        txObject.setPreviousIsolationLevel(previousIsolationLevel);
        // 设置是否只读
        txObject.setReadOnly(definition.isReadOnly());
        if (con.getAutoCommit()) {
            txObject.setMustRestoreAutoCommit(true);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
            }
        // 设置自动提交为false
            con.setAutoCommit(false);
        }
​
        this.prepareTransactionalConnection(con, definition);
 // 设置事务为激活状态      
        txObject.getConnectionHolder().setTransactionActive(true);
        int timeout = this.determineTimeout(definition);
        if (timeout != -1) {
 //设置超时时间          
            txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
        }
​
        if (txObject.isNewConnectionHolder()) {
 // 很重要的一步:绑定资源将dataSource作为key,connectHolder作为value封装在Map中,将Map添加到 【ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal("Transactional resources"); 】中,这样线程就可以从里面取出连接,进行相应的操作数据库了         
            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);
    }
}

看一下,事务状态对象中的内容:

prepareTransactionInfo

protected TransactionAspectSupport.TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm, @Nullable TransactionAttribute txAttr, String joinpointIdentification, @Nullable 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() + "]");
        }
    // 此时已经封装好了全部事务信息
        txInfo.newTransactionStatus(status);
    } else if (this.logger.isTraceEnabled()) {
        this.logger.trace("No need to create transaction for [" + joinpointIdentification + "]: This method is not transactional.");
    }
    // 将事务的信息绑定到线程的ThreadLocalMap中,也就是向ThreadLocal中添加txInfo
    txInfo.bindToThread();
    return txInfo;
}
​
// bindToThread()
     private void bindToThread() {
      // 先去获取了事务状态信息
            this.oldTransactionInfo = (TransactionAspectSupport.TransactionInfo)TransactionAspectSupport.transactionInfoHolder.get();
// 将当前的事务信息放入 ThreadLocal          
         TransactionAspectSupport.transactionInfoHolder.set(this);
        }
// transactionInfoHolder
    private static final ThreadLocal<TransactionAspectSupport.TransactionInfo> transactionInfoHolder = new NamedThreadLocal("Current aspect-driven transaction");

看一下,封装好的事务信息中的内容:

看一下ThreadLocal的继承关系图:

 至此分析完毕

总结:

 

如有问题欢迎指正讨论.....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值