Skip to content

SpringBoot 事务失效的场景

事务方法未被 Spring 管理

事务方法所在的类没有注册到 Spring IOC 容器中,也就是说,事务方法所在类并没有被 Spring 管理,则 Spring 事务会失效

方式使用 final 类型修饰

Spring 事务底层使用了 AOP,也就是通过 JDK 动态代理或者 cglib,帮我们生成了代理类,在代理类中实现的事务功能。但如果某个方法用 final 修饰了,那么在它的代理类中,就无法重写该方法,从而无法添加事务功能。这种情况事务就会在 Spring 中失效。

非 public 修饰的方法

如果事务方式不是 public 修饰,此时 Spring 事务会失效

同一个类中的方法相互调用

java
@Service
public class OrderService extend{

    private final ProductMapper productMapper;

    public void OrderService(ProductMapper productMapper) {
        this.productMapper = productMapper;
    }

    pub void submit() {
        // 其他逻辑
        this.updateProductStockById(order.getProductId(), 1L);
        return true
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateProductStockById(Integer num, Long productId) {
        productMapper.updateProductStockById(num, productId);
    }
}

方法的事务传播类型不支持事务

如果事务传播定义为 Propagation.NOT_SUPPORTED,事务会失效

异常被内部 catch

程序异常,没抛出异常

数据库不支持事务

使用 MySQL 数据库,选用 MyISAM 存储引擎,因为 MyISAM 存储引擎本身不支持事务,因此事务毫无疑问会失效。

未配置开启事务

缺少 DataSourceTransactionManager bean

错误的传播特性

参考SpringBoot 事务传播机制

多线程调用

Spring 的事务是通过 ThreadLocal 来保证线程安全的,事务和当前线程绑定,多个线程自然会让事务失效。

Released under the MIT License.