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
错误的传播特性
多线程调用
Spring 的事务是通过 ThreadLocal 来保证线程安全的,事务和当前线程绑定,多个线程自然会让事务失效。