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);
相关推荐
kimi-22229 分钟前
LangChain 将数据加载到 Chroma 向量数据库
数据库·langchain
想做后端的小C35 分钟前
Java:接口回调
java·开发语言·接口回调
爱学习的小可爱卢1 小时前
JavaEE进阶——Spring核心设计模式深度剖析
java·spring·设计模式
毕设源码-钟学长1 小时前
【开题答辩全过程】以 个性化电影推荐网站的设计与实现为例,包含答辩的问题和答案
java·spring boot
C++业余爱好者1 小时前
Power Job 快速搭建 及通信机制介绍
java
麒qiqi2 小时前
理解 Linux IO 多路复用
开发语言·数据库
MediaTea2 小时前
Python:模块 __dict__ 详解
开发语言·前端·数据库·python
qq_2704900962 小时前
SpringBoot药品管理系统设计实现
java·spring boot·后端
、BeYourself2 小时前
SpringAI-ChatClient Fluent API 详解
java·后端·springai
山峰哥2 小时前
SQL调优核心战法——索引失效场景与Explain深度解析
大数据·汇编·数据库·sql·编辑器·深度优先