REQUIRES_NEW不起作用导致整个事务回滚——Spring事务传播机制

1、Propagation.REQUIRES_NEW的作用

假设有个对象A,有a()方法,有个对象B,有b()方法。在a方法中调用了b方法,b方法被称为内嵌事务,不管a方法是否开启事务,只要b方法的事务的隔离级别为REQUIRES_NEW,则一定会在调用b方法时产生一个新的事务。

2、一个场景

A的a()方法:

    @Transactional
    public void a() {
        doSomething4A();
        B.b();//可能会抛出运行时异常
    }

内嵌在A中的B.b()方法:

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class)
    @Override
    public void b() {
        doSomething4B();
        throw new RuntimeException();//故意抛出运行时异常,观察两个事务的回滚情况
    }

在这时你肯定会想,doSomething4A会执行成功,而doSomething4B会回滚,因为我们的内嵌事务b方法的隔离级别是REQUIRES_NEW,这个方法是在一个新的事务中,回滚之后不会影响外部事务。

错错错!

事实上的运行结果是两个事务都回滚了!为什么?难道是REQUIRES_NEW失效了?

不是!仔细观察这段代码,b方法抛出异常后,并没有显示捕获,而是抛到了a方法里,a方法执行中遇到了运行时异常,也回滚了!所以b方法正确的写法应该是这样的:

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class)
    @Override
    public void b() {
        try {
            doSomething4B();
            throw new RuntimeException();//故意抛出运行时异常,观察两个事务的回滚情况
        }catch (Exception e){
            //异常处理
        }
    }
这样写后,REQUIRES_NEW就能起到这个作业啦!

你可能感兴趣的:(事务)