Spring常见的事务失效原因

一、实现原理

Spring事务的实现原理是动态代理,当调用添加@Transactional注解的方法时,代理对象会先开启事务,再调用方法,最后再提交/回滚事务。

二、常见的事务失效原因

1.修饰方法为非public

Spring事务的动态代理只会对public方法生效(jdk代理只对public方法生效,cglib代理虽然可以代理非public方法,但是在Spring中做了限制,只对public方法进行事务代理)

示例:

java 复制代码
@Service
public class UserService {
    // private修饰 → 事务失效
    @Transactional
    private void updateUserName(Long id, String name) {
        userMapper.updateName(id, name);
    }
}

2.内部方法直接调用

如果通过一个普通方法直接调用添加@Transactional的方法则会导致不走代理对象,那么也不会实现事务管理。

示例:

java 复制代码
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    // 普通方法(无事务)
    public void updateUserInfo(Long id, String name) {
        // 内部调用事务方法,不走代理 → 事务失效
        this.updateUserName(id, name); 
    }

    // 事务方法
    @Transactional
    public void updateUserName(Long id, String name) {
        userMapper.updateName(id, name);
        int i = 1 / 0; // 异常,但事务不会回滚
    }
}

3.异常类型不匹配

Spring事务只会对RuntimException和Error异常进行回滚,对检查型异常则不会触发事务回滚。

解决方法:

1.扩大异常捕获范围

java 复制代码
//捕获所有类型异常回滚

@Transactional(rollbackFor = Exception.class)

//或指定具体异常
@Transactional(rollbackFor = SQLException.class)

2.将检查型异常包装成运行时异常

java 复制代码
throw new RuntimeException(new SQLException("数据库异常"));

4.手动捕获异常且未手动回滚

手动捕获异常后,Spring无法感知到异常

java 复制代码
@Transactional
public void updateUserName(Long id, String name) {
    try {
        userMapper.updateName(id, name);
        int i = 1 / 0; // 抛出运行时异常
    } catch (Exception e) {
        // 捕获异常但未处理 → 事务提交,数据不会回滚
        log.error("更新失败", e);
    }
}

解决方法

1.在catch中触发手动回滚

java 复制代码
 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

2。显示的抛出运行时异常

java 复制代码
throw new RuntimeException(e);
相关推荐
荣码16 分钟前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
plainGeekDev2 小时前
Gson → kotlinx.serialization
android·java·kotlin
小bo波10 小时前
Java Swing 图形用户界面实验 —— 从算术练习到游戏开发的完整实践
java·课程设计·gui·游戏开发·扫雷·swing
咖啡八杯12 小时前
GoF设计模式——备忘录模式
java·后端·spring·设计模式
先吃饱再说15 小时前
存储的进化:从 MySQL 到浏览器缓存,数据到底住在哪?
数据库
Nturmoils16 小时前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
Databend18 小时前
Agent 轨迹分析与归因的数据工程实践
大数据·数据库·agent
这个DBA有点耶18 小时前
SQL改写进阶:标量子查询的“隐形代价”与消除实战
数据库·mysql·架构