Spring事务处理解析

前言

Spring 事务处理在日常开发中会频繁和其打交道,了解一下比较好。

正文

设计

Spring 事务处理逻辑中有两个最为重要的部分:一个是事务方法执行与拦截处理逻辑,一个是事务管理逻辑

实现

事务方法执行与拦截处理

从 @EnableTransactionManagement 开始 @Import(TransactionManagementConfigurationSelector.class)

  • TransactionManagementConfigurationSelector
    • AutoProxyRegistrar
      • registerAutoProxyCreatorIfNecessary 注册 AutoProxyCreator
    • ProxyTransactionManagementConfiguration
      • 构造 TransactionInterceptor 的Bean
  • AbstractAdvisorAutoProxyCreator 这个类实际上是一个 BeanPostProcessor,也就是利用了 BeanPostProcessor 这个扩展点接入 IoC 流程中
    • List findCandidateAdvisors()
  • TransactionAttributeSourceAdvisor
    • 在其中包含了上边构造的 TransactionInterceptor 的Bean
  • TransactionInterceptor
    • 注入了 PlatformTransactionManager 而 PlatformTransactionManager 则是真正用于事务处理的入口点
    • Object invoke(MethodInvocation invocation) 这个是拦截操作
      • 调用父类 的 TransactionAspectSupport 这个 invokeWithinTransaction 方法 这个方法里实际上是利用AOP机制处理事务操作得核心逻辑
        • 获得 TransactionAttribute
        • 获得 PlatformTransactionManager
        • 调用 createTransactionIfNecessary
          • 获得事务状态 PlatformTransactionManager#getTransaction
          • 绑定到线程 TransactionAspectSupport.TransactionInfo#bindToThread
        • invocation.proceedWithInvocation() 执行业务方法
        • 如果上一步抛出了异常则执行 completeTransactionAfterThrowing
          • PlatformTransactionManager#rollback 调用 PlatformTransactionManager 的回滚事务方法
        • 如果上一步正常执行完了则提交事务 commitTransactionAfterReturning
          • PlatformTransactionManager#commit 提交事务

事务管理

顶层视图是 PlatformTransactionManager

  • PlatformTransactionManager
    • getTransaction 获得事务状态
    • commit 提交事务
    • rollback 回滚事务
  • AbstractPlatformTransactionManager
    • getTransaction (里面是处理事务传播的逻辑)
      • doGetTransaction 通过具体子类获得具体的平台相关的事务对象(比如DataSourceTransactionObject)
      • if (isExistingTransaction(transaction)) 判断一下
        • 如果当前已经存在事务则 handleExistingTransaction (当前已经存在事务的情况的处理流程)
          • 处理事务传播
            • 如果是 TransactionDefinition.PROPAGATION_NEVER 则直接抛出异常
            • 如果是 TransactionDefinition.PROPAGATION_NOT_SUPPORTED
              • suspend(transaction) 暂停当前的事务
              • prepareTransactionStatus 重新准备一个新的事务
            • 如果是 TransactionDefinition.PROPAGATION_REQUIRES_NEW
              • suspend(transaction) 暂停当前的事务
              • newTransactionStatus 新建事务
              • doBegin 开始新的事务
            • 如果是 TransactionDefinition.PROPAGATION_NESTED 则嵌套执行事务
        • 如果当前不存在事务
          • 如果传播设置为 TransactionDefinition.PROPAGATION_MANDATORY 则直接抛出异常
          • 如果当前传播设置为 TransactionDefinition.PROPAGATION_REQUIRED 或者TransactionDefinition.PROPAGATION_REQUIRES_NEW 或者TransactionDefinition.PROPAGATION_NESTED
            • newTransactionStatus 新建一个事务
            • doBegin 并开始