外层方法 | 内层方法 | 执行情况 |
---|
REQUIRED | MANDATORY | - 程序正常执行,内层事务不会提交,外部事务中统一进行事务提交
- 如果内层、外层事务出现异常,在外层事务的处理中统一进行异常回滚
|
REQUIRED |
SUPPORTS |
NEVER | 外层方法不能出现事务,出现则直接报错 |
NOT_SUPPORTED | - 外层方法中有事务,直接挂起,内层方法没有异常顺利执行;如果内层方法有异常,内层方法中已经执行的数据库操作不会回滚,而外层方法事务进行回滚操作
- 如果外层方法中出现了异常操作,内部方法是不会回滚的,只有外层事务回滚
|
REQUIRES_NEW | - 外层方法存在事务,内层方法挂起外层事务,并开启一个新事务
- 程序正常执行,则内层方法优先事务提交,然后外层方法再提交
- 内层方法存在异常,内层事务优先回滚,外层方法事务也会回滚
- 外层方法存在异常,内层事务正常提交,外层方法进行回滚
|
NESTED | - 外层方法有事务,那么直接创建一个保存点
- 程序正常执行,会清除保存点,外层事务中进行提交
- 内层方法存在异常,回滚到保存点,外层方法事务会直接进行回滚
- 外层方法存在异常,内层方法正常执行,执行完毕后释放保存点,外层方法事务进行回滚
|
MANDATORY | MANDATORY | MANDATORY不可以作为外层事务,运行时必须需要一个事务 |
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其实是一个事务,外层事务可以控制内层事务的回滚,内层就算没有异常,外层出现异常,也可以全部回滚
|