Java事务失效(面试题)的常见场景

1. 方法非public修饰

原理: Spring AOP代理(CGLIB或JDK动态代理)默认无法拦截非public方法。

示例:

java 复制代码
@Service
public class UserService {
    @Transactional
    void updateUser() { // 非public方法
        // 事务不会生效!
    }
}

修复: 将方法改为public

2. 自调用(同一个类内部调用)

原理: 事务基于AOP代理,自调用绕过代理直接调用目标方法。
示例:

java 复制代码
@Service
public class OrderService {
    public void placeOrder() {
        deductStock(); // 直接内部调用,事务失效
    }

    @Transactional
    public void deductStock() {
        // 事务不生效!
    }
}

修复:

  • 从其他Bean注入自身(通过@Autowired注入代理对象)

  • 使用AopContext.currentProxy()(需开启exposeProxy

3. 异常类型错误或被捕获

场景1:抛出非RuntimeException/Error
原理: 默认只回滚RuntimeExceptionError
示例:

java 复制代码
@Transactional
public void update() throws IOException {
    if (error) throw new IOException(); // 检查型异常,不回滚!
}

修复:

添加rollbackFor属性

java 复制代码
@Transactional(rollbackFor = Exception.class)

场景2:异常被catch后未重新抛出
原理: 事务管理器检测不到异常。
示例:

java 复制代码
@Transactional
public void update() {
    try {
        db.update(...); // 抛出SQLException
    } catch (Exception e) {
        // 捕获后不抛出,事务提交!
    }
}

修复:catch中抛出RuntimeException

java 复制代码
catch (Exception e) {
    throw new RuntimeException(e);
}

4. 多线程环境下事务上下文丢失

原理: Spring事务信息存储在ThreadLocal中,新线程无法继承上下文。
示例:

java 复制代码
@Transactional
public void asyncUpdate() {
    new Thread(() -> {
        userDao.update(); // 子线程操作无事务控制!
    }).start();
}

修复:

使用Spring的@Async + Transactional(需配置异步任务执行器)

java 复制代码
@Async
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void asyncTask() {
    // 新事务生效
}

5. 数据库引擎不支持事务

原理: 如MySQL的MyISAM引擎不支持事务。
检查:

java 复制代码
SHOW TABLE STATUS LIKE 'table_name'; -- 查看Engine类型

修复: 改用InnoDB引擎。

6. 嵌套事务传播配置错误

场景: 内层事务使用Propagation.NOT_SUPPORTED
示例:

java 复制代码
@Transactional
public void outer() {
    inner();
}

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void inner() {
    // 挂起外层事务,操作无事务保护!
}

7. 非Spring管理Bean中使用@Transactional

原理: @Transactional由Spring代理实现。
错误示例:

java 复制代码
public class Util {
    @Transactional // 未被Spring管理,注解无效
    public static void save() { ... }
}
相关推荐
程序员佳佳39 分钟前
2025年大模型终极横评:GPT-5.2、Banana Pro与DeepSeek V3.2实战硬核比拼(附统一接入方案)
服务器·数据库·人工智能·python·gpt·api
qq_12498707531 小时前
重庆三峡学院图书资料管理系统设计与实现(源码+论文+部署+安装)
java·spring boot·后端·mysql·spring·毕业设计
大学生资源网1 小时前
java毕业设计之“知语”花卉销售网站的设计与实现源码(源代码+文档)
java·mysql·毕业设计·源码·springboot
小鸡脚来咯1 小时前
Redis三大问题:穿透、击穿、雪崩(实战解析)
java·spring·mybatis
roo_11 小时前
github 获取构造图数据库的LNB数据集和使用说明
数据库
桦说编程1 小时前
并发编程高级技巧:运行时检测死锁,告别死锁焦虑
java·后端·性能优化
jiayong231 小时前
Spring AI Alibaba 深度解析(三):实战示例与最佳实践
java·人工智能·spring
梁同学与Android1 小时前
Android ---【经验篇】ArrayList vs CopyOnWriteArrayList 核心区别,怎么选择?
android·java·开发语言
ss2731 小时前
从零实现线程池:自定义线程池的工作线程设计与实现
java·开发语言·jvm
苗壮.2 小时前
CommandLineRunner 是什么?
java