spring中事务传播特性,REQUIRED/REQUIRES_NEW/NESTED

spring中事务传播特性,REQUIRED/REQUIRES_NEW/NESTED

  • 结论
    • 当前方法跟被调用方法不在同一个类中时
    • 当前方法跟被调用方法在同一个类中时
  • 验证
    • 验证代码
    • 验证过程
      • 不同类调用时
      • 同一个类调用时

结论

当前方法跟被调用方法不在同一个类中时

  1. 被嵌套方法传播特性为REQUIRED
  • 内外部代码块中有一个发生代码回滚都会导致整体代码回滚。(两个事务为同一个事务)
  1. 被嵌套方法传播特性为REQUIRES_NEW
  • 内部事务与外部事务相互独立
  1. 被嵌套方法传播特性为NESTED
  • 内部事务回滚不会导致外部事务回滚,但是外部事务会导致内部事务回滚。

当前方法跟被调用方法在同一个类中时

  1. 当前方法有标记事务时,被调用方法的事务传播特性可以不管
  2. 当前方法没有标记事务时,不论被调用方法是否标记事务,当前方法中执行的代码都没有事务

验证

验证代码

@Service
public class BuyBookService {
    @Autowired
    private BookDao bookDao;
    @Autowired
    private UserDao userDao;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void subBalance(int userId) {
        userDao.subBalance(userId, 100);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void buyBook(int bookId) {
        bookDao.subBookCount(bookId, 1);
        int i = 1 / 0;
    }
}
@Service
public class PropagationService {
    @Autowired
    private BuyBookService buyBookService;

    @Transactional
    public void multi() {
        buyBookService.subBalance(1);
        buyBookService.buyBook(1);
  /**   try {
            buyBookService.buyBook(1);
        } catch (Exception e) {
            e.printStackTrace();
        }*///验证过程中会放开或注释try代码块
        System.out.println("_________________");
    }
}

验证过程

不同类调用时

修改subBalance与buyBook传播特性如下
PropagationService调用BuyBookService中方法时,subBalance为默认传播特性,修改buyBook方法的传播特性:
REQUIRED时,内部代码抛出异常
1、没有特殊设置,整体事务回滚
2、外部类代码块catch异常,整体事务依然回滚
3、内部异常事务声明noRollbackFor = ArithmeticException.class,但外部代码块未catch异常,事务依然回滚;
4、内部和外部都声明异常事务noRollbackFor = ArithmeticException.class,但外部代码块未catch异常,不会回滚事务,但是注意代码崩溃后后续代码执行问题;
5、内部异常事务声明noRollbackFor = ArithmeticException.class,外部代码块catch异常,事务不会回滚。
总结:内外部代码块中有一个发生代码回滚都会导致整体代码回滚。(两个事务为同一个事务)

REQUIRES_NEW时,内部代码抛出异常
1、没有特殊设置,整体事务回滚
2、外部类代码块catch异常,外部代码的事务不会回滚,但是内部事务会回滚
3、内部异常事务声明noRollbackFor = ArithmeticException.class,但外部代码块未catch异常,内部事务不会回滚,但外部事务会回滚;
4、内部和外部都声明异常事务noRollbackFor = ArithmeticException.class,但外部代码块未catch异常,内外事务都不会回滚,但是注意代码崩溃后后续代码执行问题;
5、内部异常事务声明noRollbackFor = ArithmeticException.class,外部代码块catch异常,内外事务不会回滚。
总结:内部事务与外部事务相互独立。

NESTED时,内部代码抛出异常
1、没有特殊设置,会导致整体事务回滚
2、外部类代码块catch异常,外部代码的事务不会回滚,但是内部事务会回滚
3、内部异常事务声明noRollbackFor = ArithmeticException.class,但外部代码块未catch异常,整体事务回滚
4、内部和外部都声明异常事务noRollbackFor = ArithmeticException.class,但外部代码块未catch异常,整体事务未回滚
5、内部和外部都声明异常事务noRollbackFor = ArithmeticException.class,外部代码块catch异常,整体事务未回滚
6、内部异常事务声明noRollbackFor = ArithmeticException.class,外部未声明,外部代码块catch异常,事务不会回滚。
总结:内部事务回滚不会导致外部事务回滚,但是外部事务会导致内部事务回滚。

同一个类调用时

将multi方法写BuyBookService中,修改subBalance与buyBook各自的传播特性如下:
REQUIRES_NEW + REQUIRES_NEW
1、未作处理,前后都回滚
2、catch异常、前后都未回滚
REQUIRED+REQUIRED
1、未作处理,前后都回滚
2、catch异常、前后都未回滚
REQUIRED+REQUIRES_NEW
1、未作处理,前后都回滚
2、catch异常、前后都未回滚
REQUIRES_NEW+REQUIRED
1、未作处理,前后都回滚
2、catch异常、前后都未回滚
总结:同一个类中调用其他有事务的方法,当前方法没有异常,事务不回滚,当前方法抛异常,事务回滚

去掉multi事务标记:
不论调用的方法有没有事务,调用方法没有标记事务都不会有事务

你可能感兴趣的:(spring,事务传播特性)