@Transactional失效场景

一、一句话结论(面试开场必说 ⭐⭐⭐⭐⭐)

@Transactional 本质是 Spring AOP 动态代理,只要事务方法没有被 Spring 代理调用,就会失效。

二、@Transactional 失效的 10 大场景(重点 ⚠️)

✅ 1️⃣ 同类方法调用(最常见 ❌)

@Service

public class UserService {

复制代码
public void outer() {
    inner(); // ❌ 事务失效
}

@Transactional
public void inner() {}

}

❌ 原因

• 调用的是 this.inner()

• 绕过了 Spring 代理

✅ 解决

• 拆到另一个 Service

• 或通过代理对象调用

✅ 2️⃣ 方法是 private(❌ 直接失效)

@Transactional

private void save() {}

❌ 原因

• Spring AOP 是基于代理实现的,private 方法无法被代理类重写或拦截,因此不能被增强。

✅ 正确写法

@Transactional

public void save() {}

✅ 3️⃣ 方法是 final / static(❌)

@Transactional

public final void save() {}

❌ 原因

• CGLIB 无法重写 final 方法

• static 不属于对象

✅ 4️⃣ 异常被 catch 吃掉(❌)

@Transactional

public void save() {

try {

int i = 1 / 0;

} catch (Exception e) {

// ❌ 不抛异常 = 不回滚

}

}

✅ 正确

catch (Exception e) {

throw e;

}

✅ 5️⃣ 抛出的异常不是 RuntimeException(❌)

@Transactional

public void save() throws Exception {

throw new Exception(); // ❌ 默认不回滚

}

✅ 解决

@Transactional(rollbackFor = Exception.class)

✅ 6️⃣ 传播行为设置错误(❌)

@Transactional(propagation = Propagation.NOT_SUPPORTED)

public void save() {}

❌ 原因

• 非事务方式执行

✅ 7️⃣ 数据库引擎不支持事务(❌)

数据库 引擎

MySQL ❌ MyISAM

MySQL ✅ InnoDB

📌 MyISAM 不支持事务

✅ 8️⃣ 未开启事务注解(❌)

// ❌ 忘了加

@EnableTransactionManagement

或 Spring Boot 未引入:

spring-tx

✅ 9️⃣ 多线程调用(❌)

@Transactional

public void parent() {

new Thread(() -> child()).start();

}

❌ 原因

• Spring 事务 绑定线程

• 子线程无事务

✅ 🔟 非 Spring 管理的 Bean(❌)

new UserService().save(); // ❌ 不在容器中

✅ 必须是:

@Autowired

UserService userService;

三、一张表彻底记住(面试救命表 ⭐⭐⭐⭐⭐)

场景 是否失效
同类方法调用
private 方法
final 方法
异常被 catch
非 RuntimeException
NOT_SUPPORTED
MyISAM
多线程
非 Spring Bean

四、面试标准回答(背这段 ✅)

@Transactional 失效主要是因为 Spring 事务基于 AOP 动态代理,常见场景包括:同类方法调用、private/final 方法、异常被捕获、异常类型不匹配、传播行为错误、数据库不支持事务、多线程调用以及 Bean 未被 Spring 管理。

五、如何快速排查事务是否生效?

✅ 1️⃣ 看日志

Creating new transaction with name ...

✅ 2️⃣ 强制异常测试

throw new RuntimeException("test");

✅ 3️⃣ 打印代理对象

System.out.println(AopContext.currentProxy());

六、最佳实践(强烈建议 ✅)

✅ 事务方法 public

✅ 不在同类中调用

✅ 明确 rollbackFor = Exception.class

✅ 不吞异常

✅ 不使用 MyISAM

✅ 不在新线程中操作事务

相关推荐
用户3521802454752 天前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
昵称为空C3 天前
手撸一个动态 SQL 执行引擎:不重启服务,在线增删改查任意数据库
spring boot·后端
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
于先生吖4 天前
SpringBoot对接大模型开发AI命理测算系统:八字排盘与AI解析接口源码全解
人工智能·spring boot·后端
Flittly4 天前
【AgentScope Java新手村系列】(10)实战-多Agent天气助手
java·spring boot·spring
星落zx4 天前
Spring Boot 多模型集成:优雅调用全球主流大模型
人工智能·spring boot·chatgpt
一杯奶茶¥4 天前
水果销售网站 CRM客户信息管理系统 超市管理系 酒店管理系统 健身房管理系统 在线音乐网站 校园招聘系统
java·vue.js·spring boot·mysql·spring·java项目
进阶的小名4 天前
Spring Boot SSE + Nginx 配置:解决 EventSource 不实时返回、连接超时、流式响应被缓冲问题
spring boot·后端·nginx
我登哥MVP4 天前
SpringCloud Alibaba 核心组件解析:服务链路追踪
java·spring boot·后端·spring·spring cloud·java-ee·maven