• Home
  • Articles
    • 日志
    • 妍小言
    • 舒小书
    • 浩然说
    • 生活日记
  • All Tags

数据库事务管理实现

26 Jul 2018

Reading time ~1 minute

数据库事务管理需求

  • 事务是可嵌套可重入的,如以下案例:

      // 准备
      @Transactional
      public void methodA(){}
    
      @Transactional
      public void methodB(){
          methodA();
      }
    
      // 场景1
      methodA()
    
      //场景2
      methodB()
    
    

    以上两个场景,均需对事务进行管理。场景一,只调用了methodA,由methodA来管理事务;场景二,同时调用了methodA和methodB,两个方法都可以进行事务管理,但此处methodB范围更广,由methodB管理事务。

  • 事务范围自由选择,开发者根据实际业务需求限定事务的范围。
  • 同一个请求可指定多个事务管理器,每一个事务管理器相互隔离,方便多数据源或者嵌套隔离,比如:

      @Transactional(transactionManager = "transactionManagerA")
      public void methodA(){}
    
      @Transactional(transactionManager = "transactionManagerB")
      public void methodB(){
          methodA();
      }
    
    

    以上两个方法使用不同事务,遵从事务的4个特性

Spring数据库事务的实现

  • 使用TransactionAspectSupport对添加了@Transactional注解的切入点进行管理,他主要做两件事情:
    1. 根据注解的配置获取相应的TransactionManager实例,他仅是事务的处理类,比如是commit还是rollback又或者不处理(因为事务嵌套),而事务具体应该如何处理,由当前事务切面的TransactionInfo决定。
    2. 收集打包当前事务切面的TransactionInfo
  • TransactionInfo数据打包
    1. 创建TransactionObject,同时尝试从当前线程上下文中获取ConnectionHolder,如果获取不到,则初始化一个并从相应的DataSource中获取链接,设置当前ConnectionHolder为Active状态。
    2. 创建TransactionStatus,根据当前线程上下文中的ConnectionHolder是否存在和其状态来定义TransactionStatus的状态,如果ConnectionHolder是新建的,则TransactionStatus状态也为新建的。
  • 事务结束时,由TransactionManager判断TransactionStatus是否为new状态,以决定是否commit操作。通过TransactionObject中持有的ConnectionHolder,对数据库链接执行相应操作。
  • 执行结束,对数据进行回收清理操作,主要是对ConnectionHolder中的事务的状态,比如savePoint和active状态等。


transaction