当前位置: 首页 > article >正文

Spring事务失效的几种场景

往期推荐

符号引用和直接引用、强引用、软引用、弱引用、虚引用-CSDN博客

已老实!再学消息队列、死信队列-CSDN博客

synchronized如何实现可重入,和Lock区别-CSDN博客

Mysql索引失效的几种场景、回表、索引覆盖、索引下推-CSDN博客

1. 未启用Spring事务管理功能或bean没有被spring管理

2. @Transactional修饰的方法非public或被final、static修饰

3. 同类的方法A直接调用同类的事务方法B

spring事务是通过Spring AOP实现的,对需要spring管理事务的bean生成了代理对象,然后通过代理对象拦截了目标方法的执行,在方法前后添加了事务的功能,所以必须通过代理对象调用目标方法的时候,事务才会起效。如果方法A直接调用方法B则是this调用,即该类的类对象,就不是代理对象。可以通过Service 类中注入自己,或者通过AopContext.currentProxy()获取代理对象来解决。

4. 抛出的异常类型错误

在业务方法进行异常抛出,spring会自动对事务进行回滚,那么问题来了,抛出哪些异常spring会回滚事务呢?默认情况下,spring遇到RuntimeException和Error的事务才会回滚。因为spring认为RuntimeException和Error是不可预期的错误,而而受检异常是可预期的错误,可以通过业务逻辑即可解决。

当然也可以自定义回滚异常类型@Transactional(rollbackFor = {异常类型列表})

5. 异常被捕获处理

spring感知到指定异常被抛出才会进行回滚,如果在方法内部捕获处理掉异常,事务就不会回滚

@Transactional
public void m1(){
    事务操作1
    try{
        事务操作2,内部抛出了异常
    }catch(Exception e){
     log.error(....)   
    }
}

正确做法是捕获处理掉异常后抛出来,如下:

@Transactional
public void m1(){
    事务操作1
    try{
        事务操作2,内部抛出了异常
    }catch(Exception e){
     log.error(....)   
     throw e
    }
}

6. 事务操作和@Transactional方法不在同一线程

@Transactional
public void m1() {
    new Thread() {
        一系列事务操作
    }.start();
}

7. 事务传播行为设置不对

spring默认事务传播行为默认是required,事务方法A内部调用事务方法B,如果方法A存在事务则方法B加入方法A的事务,否则创建新事务。如果非事务方法A调用事务方法B,事务传播级别为NOT_SUPPORT,因为方法A当前不存在事务,则方法B虽然有@Transactional注解,但仍然以非事务去执行。


http://www.kler.cn/a/549726.html

相关文章:

  • 【一文读懂】TCP与UDP协议
  • AI前端开发与跨领域合作:效率提升新纪元
  • 低空经济:开启未来空中生活的全新蓝海
  • 基于Spring Boot的民宿租赁系统的设计与实现(LW+源码+讲解)
  • unity学习43:子状态机 sub-state machine
  • 在Nodejs中使用kafka(一)安装使用
  • 【设计模式】-工厂模式(简单工厂、工厂方法、抽象工厂)
  • 股指期货是什么?股指期货日内拐点有什么特征?
  • Springer |第七届2025年区块链、人工智能和可信系统国际会议
  • frp与云服务器内网穿透
  • 实现MySQL的横向扩展
  • 一、OpenSM 架构部署及原理详解
  • Python实现语音识别详细教程【2025】最新教程
  • 41.日常算法
  • CRISPR spacers数据库;CRT和PILER-CR用于MAGs的spacers搜索
  • MySQL创建存储过程和存储函数
  • 人工智能在文化遗产保护中的创新:科技与文化的完美融合
  • 【ENSP】华为设备console 认证配置
  • Ubuntu 系统 LVM 逻辑卷扩容教程
  • uni-app 学习(一)