Spring事务传播机制和隔离级别

面试必问的Spring事务传播机制和隔离级别,本质上是在解决两个核心问题:多个事务如何协作(传播机制)和并发操作如何避免数据混乱(隔离级别)。搞懂这两点,数据库操作就能既安全又高效。
📁 2025年Java面试宝典:
链接
提取码: 9b3g
一、Spring事务传播机制:事务如何接力?
传播机制定义了“当多个事务方法互相调用时,事务该合并还是另起炉灶”。常见的有7种:
-
REQUIRED(默认):
- 当前有事务就加入,没有就新建。像团队协作,能合并就合并。
- 比如下单扣库存+记日志,两个方法共用同一事务,失败一起回滚。
-
REQUIRES_NEW:
- 强制开新事务,老事务暂停。适合独立操作,比如发短信通知——就算订单失败,通知也得发。
-
SUPPORTS:
- 有事务就加入,没有就非事务运行。类似查询方法,不强制要求事务环境。
-
NOT_SUPPORTED:
- 非事务执行,挂起当前事务。比如调用外部API,避免长事务阻塞。
-
NEVER:
- 严禁在事务中调用!否则直接报错。用于严格非事务场景。
📌 面试点拨:选传播类型要看业务关联性。强依赖用REQUIRED(比如支付+扣券),弱依赖用REQUIRES_NEW(比如日志记录)。
二、事务隔离级别:并发操作如何避坑?
隔离级别解决“多个事务同时改数据时,互相能看到多少改动”。Spring支持4种标准级别:

-
读未提交(Read Uncommitted):
- 事务A能读到事务B未提交的数据。可能脏读(读到无效数据),性能高但危险,极少用。
-
读已提交(Read Committed):
- 只能读到已提交的数据(默认级别)。解决脏读,但可能有不可重复读问题(两次读结果不一致)。
-
可重复读(Repeatable Read):
- 同一事务多次读结果一致。MySQL默认级别,用MVCC避免不可重复读,但可能有幻读(新增数据影响统计)。
-
串行化(Serializable):
- 事务排队执行,彻底避免并发问题。性能最差,像单线程操作数据库。
🔍 面试场景:
- 问:订单系统扣库存遇到超卖怎么办?
- 答:在REQUIRED事务中用可重复读隔离级别+乐观锁(version字段),保证并发时数据准确。
三、实际开发中的避坑指南
-
传播机制坑点:
- REQUIRES_NEW开太多事务会导致数据库连接耗尽!
- 嵌套事务(NESTED)部分回滚需数据库支持(如Oracle),MySQL不支持。
-
隔离级别陷阱:
- 默认隔离级别可能不满足业务,比如财务系统需显式声明串行化。
- 高并发场景慎用串行化,用乐观锁替代。
💡 小技巧:
在Spring中声明事务:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ) public void placeOrder() { ... }
四、高频面试题破解
Q:事务方法调用同类另一个事务方法为何失效?
A:这是Spring AOP的代理机制问题——同类调用不走代理!解决:
- 拆到不同类
- 用AopContext.currentProxy()获取代理对象再调用
Q:@Transactional在private方法上为啥不生效?
A:动态代理需通过public方法切入,private方法无法被代理。
💸 提个醒:如果需要购买面试鸭会员,可以上面试鸭返利网找我,返25元!帮你省杯咖啡钱~

搞懂传播机制和隔离级别,面试官再问事务问题,你就能淡定甩出底层逻辑:“传播管事务协作,隔离管并发安全”——这句话就能拿印象分!


