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);
相关推荐
小陈工1 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
一定要AK5 小时前
Spring 入门核心笔记
java·笔记·spring
A__tao5 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
KevinCyao5 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
科技小花5 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸5 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
凯尔萨厮5 小时前
创建SpringWeb项目(Spring2.0)
spring·mvc·mybatis
D4c-lovetrain5 小时前
linux个人心得22 (mysql)
数据库·mysql
迷藏4945 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
阿里小阿希6 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql