面试鸭返利网

spring事务隔离级别和传播性

Spring事务隔离级别和传播性是Java面试必考重点,掌握READ_COMMITTED默认隔离级别和REQUIRED传播行为是关键。深入理解脏读、不可重复读、幻读等并发问题,以及REQUIRES_NEW与NESTED的区别,能帮助开发者设计高并发系统。本文详解四种隔离级别和七种传播行为,提供实战避坑指南,解决@Transactional不生效等常见问题,助力开发者应对分布式事务挑战,提升系统性能和稳定性。

Spring事务隔离级别和传播性

面试鸭返利网
2025年Java面试宝典抢先领
🔗 网盘链接 提取码: 9b3g


一、事务隔离级别到底是什么?

面试官问Spring事务隔离级别时,其实在考察你对数据库并发问题的理解。Spring直接沿用了数据库的四种标准隔离级别:

  1. READ_UNCOMMITTED(读未提交)
    最宽松的级别,能读到别人未提交的数据。可能引发脏读——比如你读到同事正在修改但还没提交的订单金额,结果他回滚了,你拿的就是错误数据。

  2. READ_COMMITTED(读已提交)
    Spring默认隔离级别!只读取已提交的数据。解决了脏读,但可能有不可重复读问题——同一事务内两次查询结果不同(比如中间数据被其他事务修改了)。

  3. REPEATABLE_READ(可重复读)
    保证同一事务多次读取数据一致。但可能有幻读——你查订单表10条记录,这时别人新增一条订单,你再查变成11条了(MySQL的InnoDB通过间隙锁基本解决了幻读)。

  4. SERIALIZABLE(串行化)
    性能最低但最安全,所有操作串行执行,彻底解决并发问题。

👉 面试技巧:被问到“Spring事务默认隔离级别”时,一定要强调是READ_COMMITTED,并解释为什么(平衡性能与安全)。


二、传播性:事务嵌套的生存法则

面试鸭返利网
事务传播性解决的是“方法A调用方法B时,B的事务如何加入A”的问题。核心七种传播行为:

| 传播行为 | 典型场景 | |-------------------|--------------------------------------------------------------------------| | REQUIRED(默认) | 如果当前有事务就加入,没有就新建。比如下单操作调用扣库存和写订单日志 | | REQUIRES_NEW | 挂起当前事务,新建独立事务。比如写操作日志必须成功,不受主事务回滚影响 | | NESTED | 嵌套事务,子事务回滚不影响主事务(Savepoint机制)。适用于可独立回滚的子操作 | | SUPPORTS | 有事务就加入,没有就非事务执行。适合查询方法 | | NOT_SUPPORTED | 非事务执行,挂起当前事务。比如需要强制读数据库最新数据的统计操作 | | MANDATORY | 必须在已有事务中运行,否则抛异常。用于强制事务上下文 | | NEVER | 必须在非事务环境执行,否则抛异常 |

高频面试题
❓ “REQUIRES_NEW和NESTED有什么区别?”
REQUIRES_NEW:完全独立事务,互不影响
NESTED:嵌套事务,子事务回滚不影响主事务,但主事务回滚会导致子事务回滚(基于Savepoint实现)


三、面试官最爱挖的坑

  1. 坑1:@Transactional不生效

    • 原因:自调用(方法A调本类方法B)、非public方法、异常被catch未抛出、数据库引擎不支持事务(如MyISAM)
  2. 坑2:错误使用传播行为

    // 错误示例:在循环中频繁创建新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void processItem(Item item) { ... }
    

    这样写会导致每个循环项都开新事务,性能急剧下降!

  3. 坑3:混淆隔离级别和传播性

    • 隔离级别解决的是“多个事务同时操作数据时如何隔离”
    • 传播性解决的是“事务方法相互调用时如何传递”

四、实战避坑指南

面试鸭返利网
避坑口诀

默认隔离READ_COMMITTED,
传播就用REQUIRED。
特殊场景显声明,
嵌套独立要分清!

返利小贴士

🎉 需要开通面试鸭会员?通过 面试鸭返利网 找我下单,可额外返现25元!后台私信订单号即可~


延伸思考
Spring的@Transactional注解本质是通过AOP代理实现的,所以同类自调用会失效。解决方案:

  1. 将内部方法抽到新类中
  2. 通过AopContext获取代理对象(需开启@EnableAspectJAutoProxy(exposeProxy = true)
  3. 最简单粗暴的——直接用this.serviceB.method()(但要注意循环依赖)

理解清楚Spring事务隔离级别和传播性,能让你在分布式事务、高并发场景的设计中游刃有余。面试时结合具体业务场景说明选型依据,绝对是加分项!

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

立即加入面试鸭会员 →