入口

我们还是先从入口说起,TransactionAutoConfiguration是一个EnableAutoConfiguration类跟随着spring boot启动被加载进来,从这里我们可以看得出Spring Boot默认会启动EnableTransactionManagement打开事务支持。
image.png
接下来我们来看下EnableTransactionManagement这个注解,跟Spring Boot其他EnableXXX注解一样都@Import了一个ImportSelector类来完成事务的初始化。
image.png
TransactionManagementConfigurationSelector引入两个Bean:

  • AutoProxyRegistrar:// TODO : 后面AOP原理解析再补充
  • ProxyTransactionManagementConfiguration:核心配置

image.png
image.png
这里实例化了3个对象:

整个事务管理基于AOP机制进行,通过织入拦截点对方法进行拦截,然后委托给TransactionInterceptor进行处理,如下图所示:
image.png

BeanFactoryTransactionAttributeSourceAdvisor

通过CglibAopProxy的内部类ProxyCallbackFilter来获取切面,这个不做重点讲,主要就是利用了Spring AOP机制来实现切面通知

TransactionAttributeSource

这个类的职责比较简单就是利用SpringTransactionAnnotationParser解析器来判断拦截的方法是否带有@Transactional注解,若有则解析出里面的属性拼装成一个TransactionAttribute并返回

TransactionInterceptor

这个拦截器是Spring 事务管理的核心,我们这个章节将着重讲讲这个拦截器。拦截器核心方法为invoke通过动态代理的方式调用该方法,然后委托给TransactionAspectSupport这个子类的invokeWithinTransaction进行处理
image.png
事务核心处理逻辑分为3种情况:

  • Reactive事务管理,这个是响应式编程的一部分,具体感兴趣读者可以webflux相关资料
  • 普通的事务管理,这个是我们的核心,大部分请求使用的即是该逻辑,我们具体讲这部分逻辑
  • 回调式事务管理,这种可以参考TransactionTemplate的使用方法

image.png
主体逻辑也是十分简单,主要就是开启事务,执行方法,然后根据异常情况commit或者rollback
image.png
这里事务的TransactionManager默认使用的是JdbcTransactionManager,开启事务的过程比较简单,就是新建一个事务然后把事务搬到当前线程中就行createTransactionIfNecessary->prepareTransactionInfo->bindToThread,然后使用动态代理的方式执行方法调用proceedWithInvocation,执行结束后根据情况提交或者回滚事务completeTransactionAfterThrowing、commitTransactionAfterReturning,这里稍微讲下cleanupTransactionInfo这个方法回去调用TransactionInfo中的restoreThreadLocalStatus,我们可以看到这个方法是将线程变量设置为老的那个transactionInfo,这里为啥要这样做呢,我的理解应该是为了实现事务隔离,比如内嵌事务这种场景。
image.png
在上上面那个代码块里面还使用了VavrDelegate,点击查看Vavr库
image.png

事务传播机制

事务传播级别位于TransactionDefinition进行定义,如下图:(载自这篇文章

  • PROPAGATION_xx : Spring事务传播级别
    • PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。(默认)
    • PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
    • PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常
    • PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起
    • PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务
    • PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常
    • PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, PROPAGATION_REQUIRED 属性执行
  • ISOLATION_xx: 数据库隔离级别
    • ISOLATION_READ_UNCOMMITTED:读未提交
    • ISOLATION_READ_COMMITTED :读提交(mysql默认)
    • ISOLATION_REPEATABLE_READ :重复读(推荐使用,避免间隙锁)
    • ISOLATION_SERIALIZABLE :串行化(性能低)

image.png

TransactionalEventListener事务监控使用说明

TODO