事务回滚的判断
基于注解中的配置信息,可以得出超时或者抛出指定异常的情况下,会执行事务的回滚。
但是默认超时时间是-1,即不设超时时间
指定抛出异常的话默认是对RuntimeException和Error的子类
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
Class<? extends Throwable>[] rollbackFor() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
1.REQUIRED
REQUIRED是@Transactional 默认的传播等级,即如果当前存在事务则不再创建新事物。如果当前不存在事务则新建事务。
举例:ServiceA 调用 ServiceB
情况 1. A开启了事务且传播等级为REUQIRED,那么B则不会新建事务,如果抛出异常的话AB一起回滚
2. A如果没有开启事务,B开启事务则是B异常回滚,A不受影响
2. REQUIRED_NEW
会新建事务,当前如果存在事务则挂起当前事务重新创建事务。
举例:ServiceA 调用 ServiceB(A为REUQIRED级别,B为REQUIRED_NEW级别)
情况 1. A调用B,如果B已经提交了,说明B的事务已经执行完成了。这时候A抛出异常,那么只会将A的事务回滚。
2. A调用B,B抛出异常且事务回滚了,这时候如果异常被A捕获到,那么具体看对捕获的异常的处理来判断是否回滚。但是如果没有捕获到的话那么A肯定回滚。
3. SUPPROT
支持当前事务,如果无事务则按非事务方式运行
举例:ServiceA 调用 ServiceB
情况 1. ServiceB配置事务传播等级为SUPPORT , 那么B是否按事务方式运行全看A是否有事务。如果A存在事务,则AB在一个事务内,有异常全部回滚。
4. NOT_SUPPROT
不支持当前事务,如果有事务则将当前事务挂起,以非事务的状态运行
举例:ServiceA 调用 ServiceB(A -> REQUIRED , B -> NOT_SUPPORT )
情况 1. 无论A是否存在事务,B都是会按非事务状态去执行
5. NEVER
不支持事务,如果当前存在事务,则抛出异常
举例:ServiceA 调用 ServiceB(A为REUQIRED级别,B为NEVER 级别)
情况 1. A 调用 B , B直接抛出异常。
6. MANDATORY
支持当前事务,如果当前没有事务则抛出异常
举例:ServiceA 调用 ServiceB
情况 1. 如果A未配置事务,B配置传播等级为MANDATORY则直接抛出异常,如果A配置事务,则正常执行AB在同一事务内。
7. NESTED
如果当前存在事务,则会创建一个嵌套的子事务,且在嵌套的子事务内执行。如果不存在事务,那么和REQUIRED差不多
举例:ServiceA 调用 ServiceB
失败回滚状态:
1. B已经提交成功 如果A失败回滚 B进行回滚操作
2. B失败回滚 如果抛出的异常在A中被try catch捕获处理 则A看处理结果判断是否进行失败回滚 ,若没有没A捕获处理 则A肯定回滚
使用NESTED的重点
1.设置 transactionManager 的 nestedTransactionAllowe 为 true, 默认值是false。
2. JDBC driver 必须支持 JDBC 3.0
3. JDK 版本必须 1.4 +