spring事务传播详解

事务失效场景注意

  • spring 事务时通过spring aop实现的,通过this关键字调用方法时,没有通过代理类代理方法,导致事务失效

  • Spring的默认的事务规则是遇到运行异常(RuntimeException)和程序错误(Error)才会回滚。或者指定回滚异常

  • 自己捕获异常

  • 方法定义非public

  • 方法定义为final

事务挂起

可以理解为方法栈,挂起即保存事务的当前状态,在方法返回后恢复保存的事务状态

Springboot中,事务的注解如下:

@Transactional(propagation = Propagation.REQUIRED)

其中,Propagation有7个常量值,常用的有REQUIRED和SUPPORTS,下面是各种值的解释:

存在两个方法,A ,B,A方法调用B方法

  1. PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
  • B方法事务添加此注解
    • A方法存在事务,B方法加入A事务。即使 A方法中 对B方法进行了try catch操作,两个事务也会保持一致性。在A事务的结尾会抛出异常Transaction rolled back because it has been marked as rollback-only
    • A方法不存在事务,B方法创建一个新的事务
  1. PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  • B方法事务添加此注解
    • A方法存在事务,B方法加入A事务
    • A方法不存在事务,B方法也不存在事务
  1. PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
  • B方法事务添加此注解
    • A方法存在事务,B方法加入A事务
    • A方法不存在事务,B方法抛出异常
  1. PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  • B方法事务添加此注解
    • A方法存在事务,A方法事务挂起,B方法事务独立,与A事务无关。但B方法的异常会返回给A方法,导致B方法事务回滚会影响A方法事务回滚。
    • A方法不存在事务,B方法事务独立
  1. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • B方法事务添加此注解
    • A方法存在事务,A方法事务挂起,B方法不存在事务,与A事务无关。但B方法的异常会返回给A方法,导致B方法抛出的异常会导致A方法事务回滚。
    • A方法不存在事务,B方法也不存在事务
  1. PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • B方法事务添加此注解
    • A方法存在事务,抛出异常
    • A方法不存在事务,B方法也不存在事务
  1. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
  • B方法事务添加此注解
    • A方法存在事务,B方法加入A事务。 如果A方法中 对B方法进行了try catch操作,B事务回滚不影响A事务
    • A方法不存在事务,B方法创建一个新的事务

NESTED申明在被调用方法上,若调用者方法有开启事务。此时NESTED会开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务。 潜套事务开始执行时, 它将取得一个 savepoint。 如果这个嵌套事务失败, 我们将回滚到此 savepoint。 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。

posted @ 2022-09-23 17:50  雾里看花的少年  阅读(119)  评论(0编辑  收藏  举报