08-TX传播特性

传播属性描述
REQUIRED(默认)加入当前事务;如果没有,新建一个
SUPPORTS加入当前事务;如果没有,非事务运行
MANDATORY加入当前事务;如果没有,抛出异常
REQUIRES_NEW挂起当前事务;新建事务运行
NOT_SUPPORTED挂起当前事务;如果没有,非事务运行
NEVER当前事务,抛异常;如果没有,非事务运行
NESTED当前事务设置保存点,新建嵌套事务运行。如果没有,新建事务运行
image-20221224151846778
外层方法内层方法执行情况
REQUIREDMANDATORY
  • 程序正常执行,内层事务不会提交,外部事务中统一进行事务提交
  • 如果内层、外层事务出现异常,在外层事务的处理中统一进行异常回滚
REQUIRED
SUPPORTS
NEVER外层方法不能出现事务,出现则直接报错
NOT_SUPPORTED
  • 外层方法中有事务,直接挂起,内层方法没有异常顺利执行;如果内层方法有异常,内层方法中已经执行的数据库操作不会回滚,而外层方法事务进行回滚操作
  • 如果外层方法中出现了异常操作,内部方法是不会回滚的,只有外层事务回滚
REQUIRES_NEW
  • 外层方法存在事务,内层方法挂起外层事务,并开启一个新事务
  • 程序正常执行,则内层方法优先事务提交,然后外层方法再提交
  • 内层方法存在异常,内层事务优先回滚,外层方法事务也会回滚
  • 外层方法存在异常,内层事务正常提交,外层方法进行回滚
NESTED
  • 外层方法有事务,那么直接创建一个保存点
  • 程序正常执行,会清除保存点,外层事务中进行提交
  • 内层方法存在异常,回滚到保存点,外层方法事务会直接进行回滚
  • 外层方法存在异常,内层方法正常执行,执行完毕后释放保存点,外层方法事务进行回滚
MANDATORYMANDATORYMANDATORY不可以作为外层事务,运行时必须需要一个事务
REQUIRED
SUPPORTS
NEVER
NOT_SUPPORTED
REQUIRES_NEW
NESTED
SUPPORTS

NEVER

NOT_SUPPORTED
MANDATORY外层方法不包含事务,内层方法获取事务直接报错。外层方法不包含事务,所以无需回滚
SUPPORTS
  • 内外层方法都不包含事务,会以无事务方法开始运行,每个数据库操作直接执行即可
  • 出现异常情况,后续操作不会执行,已经执行过的数据库操作不受任何影响
NEVER
NOT_SUPPORTED
REQUIRED
  • 外层方法不包含事务,内层方法新建事务
  • 程序正常执行,那么事务会正常提交
  • 内层方法出现异常,内层方法事务正常回滚,而外层事务不做任何处理
  • 外层方法出现异常,内层方法事务正常提交,外层方法抛出异常
REQUIRES_NEW
NESTED
REQUIRES_NEW

NESTED
MANDATORY
  • 程序正常执行,内层事务不会提交,外部事务统一进行提交
  • 内层、外层事务中出现异常,外层事务统一进行异常回滚
REQUIRED
SUPPORTS
NEVER外层方法出现事务,直接报错
NOT_SUPPORTED
  • 外层方法中有事务,直接挂起
  • 内层方法没有异常直接顺利执行
  • 内层方法有异常,内层方法已经执行的操作不会触发回滚,外层方法事务进行回滚
  • 外层方法出现异常,内部方法不会回滚,只有外层事务回滚
REQUIRES_NEW
  • 外层方法存在事务,内层方法挂起外层事务并开启一个新事务
  • 程序正常执行,内层方法优先事务提交,然后外层方法再提交
  • 内层方法存在异常,内层事务优先回滚,外层事务也会回滚
  • 外层方法存在异常,内层事务正常提交,外层方法进行回滚
NESTED
  • 外层方法有事务,直接创建一个保存点;外层方法没有事务,就创建一个新的事务
  • 程序正常执行,没有异常,清除保存点,并且外层事务进行提交
  • 内层方法中存在异常,回滚到保存点,外层事务直接进行回滚
  • 外层方法存在异常,内层方法正常执行,完毕后释放保存点,并且外层方法事务会进行回滚

1. REQUIRED、NESTED回滚的区别
  • 最大区别在于保存点的设置,外层方法对内层方法的异常情况进行捕获时区别很大,两者报的异常信息不同
  • REQUIRED时,会报Transaction rolled back because it has been marked as rollback-only信息。因为内部异常,设置了回滚标记,外部捕获之后,要进行事务的提交,此时发现有回滚标记,要回滚,所以报异常
  • NESTED不会出现这种情况,在回滚时把回滚标记清除了,外部捕获异常后去提交,没发现回滚标记,正常提交

2. REQUIRES_NEW、REQUIRED区别
  • 两种方式产生的效果一样,REQUIRES_NEW会有新连接生成;NESTED使用的是当前事务的连接,可以回滚到保存点
  • REQUIRES_NEW每次都是一个新的事务,没有办法控制其他事务的回滚,但NESTED其实是一个事务,外层事务可以控制内层事务的回滚,内层就算没有异常,外层出现异常,也可以全部回滚