Spring事务回滚不生效?程序员亲测排查指南
2025年Java面试宝典:点击领取(提取码:9b3g)
作为Java开发者,面试时被问“Spring事务没回滚怎么办?”绝对是个高频题!今天咱们就直击痛点,聊聊排查思路,全是实战干货👇
🔍 一、Spring事务生效了吗?
首先得确认事务真的开启了!很多新手栽在这儿:
- 检查注解位置:
@Transactional必须加在 public方法 上!加在private/internal方法上等于白写。 - 是否被代理:Spring通过AOP代理实现事务。如果调用的方法来自同一个类内部调用(如A方法调本类B方法),B的事务注解不会生效!

- 配置是否漏配:XML或Java Config里,确认开启了
<tx:annotation-driven/>或@EnableTransactionManagement。
⚠ 二、异常类型对了吗?
Spring默认只对RuntimeException和Error回滚! 这是最常踩的坑!
@Transactional
public void updateData() throws Exception {
try {
// 数据库操作
throw new Exception("一个Checked Exception!"); // ❌ 不会回滚!
} catch (Exception e) {
// 吞掉异常 -> ❌ 不会回滚!
}
}
✅ 解决方案:
- 抛出
RuntimeException或子类(如NullPointerException)。 - 在
@Transactional里指定回滚的异常类型:
@Transactional(rollbackFor = Exception.class)// 所有异常都回滚 - 绝对不要吞掉异常!让异常抛出到事务切面。
🧩 三、事务传播机制搞懂没?
不同的propagation行为影响事务边界:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodA() {
// 开启新事务
methodB(); // 调用methodB
}
@Transactional(propagation = Propagation.REQUIRED)
public void methodB() {
// 如果methodB抛异常,methodA的事务会回滚吗?看配置!
}
- REQUIRED(默认):加入当前事务,一起提交/回滚。
- REQUIRES_NEW:开启独立事务,外层事务回滚不影响它。
- NESTED:嵌套事务,部分数据库(如Oracle)支持。

⏹ 四、手动回滚怎么用?
有时捕获异常后需手动触发回滚:
@Transactional
public void process() {
try {
// 业务逻辑
} catch (BizException e) {
// 记录日志后手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // ✅
}
}
🧪 五、数据库引擎背锅?
MyISAM引擎不支持事务! 确认你的表用的是InnoDB:
SHOW TABLE STATUS LIKE 'your_table';

🎯 总结关键点
- 注解位置:public方法 + 避免自调用。
- 异常类型:默认回滚RuntimeException,其他需配置
rollbackFor。 - 传播行为:理解REQUIRED/REQUIRES_NEW区别。
- 手动回滚:
setRollbackOnly()是救星。 - 数据库引擎:认准InnoDB!
🎁 福利时间:如果需要购买“面试鸭会员”,通过 面试鸭返利网 找我下单,额外返利25元!备考更省钱✅
搞透这些点,面试官问你“Spring事务回滚为什么没生效”时,绝对能滔滔不绝!面试题库和实战技巧可以看开头分享的宝典资源~ 觉得有用欢迎分享给队友! 🚀


