spring事务传播详解
事务失效场景注意
-
spring 事务时通过spring aop实现的,通过this关键字调用方法时,没有通过代理类代理方法,导致事务失效
-
Spring的默认的事务规则是遇到运行异常(RuntimeException)和程序错误(Error)才会回滚。或者指定回滚异常
-
自己捕获异常
-
方法定义非public
-
方法定义为final
事务挂起
可以理解为方法栈,挂起即保存事务的当前状态,在方法返回后恢复保存的事务状态
Springboot中,事务的注解如下:
@Transactional(propagation = Propagation.REQUIRED)
其中,Propagation有7个常量值,常用的有REQUIRED和SUPPORTS,下面是各种值的解释:
存在两个方法,A ,B,A方法调用B方法
- PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
- B方法事务添加此注解
- A方法存在事务,B方法加入A事务。即使 A方法中 对B方法进行了try catch操作,两个事务也会保持一致性。在A事务的结尾会抛出异常Transaction rolled back because it has been marked as rollback-only
- A方法不存在事务,B方法创建一个新的事务
- PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
- B方法事务添加此注解
- A方法存在事务,B方法加入A事务
- A方法不存在事务,B方法也不存在事务
- PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
- B方法事务添加此注解
- A方法存在事务,B方法加入A事务
- A方法不存在事务,B方法抛出异常
- PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
- B方法事务添加此注解
- A方法存在事务,A方法事务挂起,B方法事务独立,与A事务无关。但B方法的异常会返回给A方法,导致B方法事务回滚会影响A方法事务回滚。
- A方法不存在事务,B方法事务独立
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- B方法事务添加此注解
- A方法存在事务,A方法事务挂起,B方法不存在事务,与A事务无关。但B方法的异常会返回给A方法,导致B方法抛出的异常会导致A方法事务回滚。
- A方法不存在事务,B方法也不存在事务
- PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- B方法事务添加此注解
- A方法存在事务,抛出异常
- A方法不存在事务,B方法也不存在事务
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
- B方法事务添加此注解
- A方法存在事务,B方法加入A事务。 如果A方法中 对B方法进行了try catch操作,B事务回滚不影响A事务
- A方法不存在事务,B方法创建一个新的事务
NESTED申明在被调用方法上,若调用者方法有开启事务。此时NESTED会开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务。 潜套事务开始执行时, 它将取得一个 savepoint。 如果这个嵌套事务失败, 我们将回滚到此 savepoint。 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。