@Transactional不生效的场景

@Transactional概述

@Transactional注解可以加在方法、类和接口上,加在类和接口上等于给类中的每个public方法都添加了@Transactional,在使用时尽量直接加在方法上。@Transactional属性及说明见下表:
image

  1. name:一般只有1个事务管理器,默认即可,无需指定。
  2. propagation:事务的传播行为。默认是Propagation.REQUIRE适用百分之90的场景,默认即可
  3. isolation:事务隔离级别,默认即可
  4. timeout:事务超时时间,默认即可
  5. readOnly: 是否只读事务,默认即可
  6. rollbackFor:触发事务回滚的异常类型。这个就不能随便默认了,@Transactional只能检测到unchecked异常和error。
  7. noRollbackFor: 触发事务回滚的异常类型。默认即可

PS:

  1. 比如RuntimeExeption,NointerException...等编译器在编译前检测不出来的异常,属于unchecked异常。
  2. 像checked异常,如IOException...等编译器可检测出来,即需开发人员手动处理(try-catch或者throws)的异常是检测

@Transactional常见不生效的场景

用在非public方法

@Transactional修饰的方法必须是public,不然会失效。

同一个类中,非@Transactional方法调用@Transactional方法

举个简单的例子,AController调AService的A方法,A方法再调用 AService的B方法,B方法上加了@Transactional;这种场景是会失效的,即使多次更新操作数据库都在B方法里也同样

如何避免:建议大家在调用链首个被调用Service方法上加@Transactional。按上面的举例,即在A方法上加

Service方法中使用try-catch

很简单,在方法中抛出异常被try-catch捕获了,@Transactional会认为是正常执行,不会进行回滚

如何避免:尽量少在service中使用try-catch,可以放到controller进行处理。如果非要使用,也请记得catch中再抛出unchecked异常

方法抛出checked异常

@Transactional只能监测到unchecked异常;如果是checked异常,可以使用rollbackFor指定具体的checked异常,这样就可以拦下来进行回滚了

posted @ 2022-08-31 14:39  爱编程DE文兄  阅读(505)  评论(0编辑  收藏  举报