spring事务传播机制浅述

109 阅读2分钟

初识spring事务传播机制的时候,脑子一头雾水,想呀一个事务也能搞出来那么多东西,这不是故意搞复杂了吗?当时真的是人越是菜的时候,越是比较自信。毕竟在以前学习数据库事务的时候,只有提交和回滚。当时也没有仔细研究,就随便背一下,应付面试而已,直到我遇到了一个让我很头疼的需求,一个请求需要调用三个方法,就假设为方法A、B和C,一般情况下,这三个方法都成功则提交,其中任何一个失败就回滚,而这次要求B失败不影响A、C,只回滚B本身操作的数据。在此情况下,挠破脑袋也想不到如何解决,差点直接对这个需求弃用spring了,用原生办法实现,建立两个数据库连接,B单独用一个连接处理。从网上仔细找了一下解决方案,有人说可以用spring事务传播机制处理,就仔细研究了一下,发现里面的功能真厉害,完美解决了这个问题。此上都是我研究spring事务的背景,下面开始我对spring事务的简单浅述。

    {
     A();
     B();
     C();
    }

背景

数据库连接是和事务一一绑定的。

REQUIRED

在方法上直接加@Transactional,spring事务默认的传播机制就是REQUIRED,如果当前没有事务,则创建一个新的事务,如果当前存在事务,子方法加入当前事务,形成一个整体。
也就是说,使用REQUIRED,若是A、B和C方法都是使用的此机制,则他们都是在一个连接中执行,若有一个报错,则全部回滚。
类似于如下的代码:

    {
         conn = new Connection()
         try{
             A(conn);
             B(conn);
             C(conn);
             conn.commit();
         }catch(Exception e){
            conn.rollback();
         }
    }

REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRES_NEW)注解上加入此事务传播方式,挂起当前事务,新建一个事务处理此方法。此方式就可以实现我当时所遇到的问题。
假设方法A和C的事务传播机制采用REQUIRED,B方法采用REQUIRES_NEW,则方法A和C会由一个连接处理,B方法会由另一个连接处理。

    {
         conn = new Connection()
         try{
             A(conn);
             try{
                 conn1 = new Connection()
                 B(conn1);
             }catch(Exception e){
                conn1.rollback();
             }
             C(conn);
             conn.commit();
         }catch(Exception e){
            conn.rollback();
         }
    }