Spring事务传播级别

事务的传播机制定义了一个方法被另一个事务方法调用的时候,这个事务的方法行为该如何,定义了事务的边界和事务上下文在方法调用链中传播

img

img

Spring事务隔离级别

ISOLATION_DEFAULT: 使用后端默认的事务隔离级别,MySQL是可重复读,Oracle是读已提交

  • ISOLATION_READ_UNCOMMIT: 读未提交
  • ISOLATION_READ_COMMIT: 读已提交
  • ISOLATION_REPEATABLE_READ: 可重复读
  • ISOLATION_SERIALIZABLE: 串行化

声明式事务失效的场景

  • MySQL存储引擎是MyISAM,不支持事务
  • Spring的声明式事务是基于代理模式的。由于java继承时, 不能重写 private , final , static 修饰的方法,所以private 方法, final 方法 和 static 方法都没有事务支持
  • 如果在开启事务的方法,事务try-catch捕获异常但没有抛出异常,事务不会起效
  • 在不同类的方法调用,如果A方法开启了事务,B方法没有开启事务,B方法调用A
    • 如果B方法发生异常,但不是调用的A产生的,事务失效
    • 如果B方法发生异常,但是调用的A产生的,事务有效
    • 在B方法上加上@Trasactional,一定会生效
  • 同类方法调用,会失效。这是因为内部方法调用不会通过 Spring 生成的代理类进行调用,而是直接在当前对象中执行,因此 Spring 无法介入处理事务
  • 如果使用了Spring+MVC,context:component-scan 重复扫描问题可能会引起事务失效。
    • 如果spring和mvc的配置文件中都扫描了service层,那么事务就会失效
    • 原因:因为spring ioc中子容器可以加载父容器,父容器不能加载子容器。这里springmvc相当于子容器。按照spring配置文件的加载顺序来讲,先加载springmvc配置文件,再加载spring配置文件,我们的事务一般都在spring配置文件中进行配置,如果此时在加载springMVC配置文件的时候,把service也给注册了,但是此时事务还没加载,也就导致后面的事务无法成功注入到service中。所以把对service的扫描放在spring配置文件