Spring 事务传播行为与隔离级别

通俗易懂!2025 年最新版 Spring 事务传播行为 + 隔离级别全家福
背完这篇,大厂随便问“事务传播行为”“隔离级别”“脏读幻读怎么解决”,你都能 30 秒画图 + 甩口诀直接秒杀!

一、7种传播行为(Propagation)—— 面试必背前4个就吃遍天

传播行为大白话解释真实使用频率经典场景
REQUIRED(默认)有事就加入,没事就自己开一个99.9%日常增删改查全部用这个
REQUIRES_NEW老子不管你有没有,我都要新开一个事务★★★★★日志、发邮件、审计(必须成功,不能被主事务回滚)
NESTED如果有事务,就在里面插个“存档点”(savepoint)★★★主事务里想部分回滚(比如保存订单成功,但发优惠券失败只回滚发券)
SUPPORTS有就加入,没有也无所谓★★查详情、导出报表(读多写少)
NOT_SUPPORTED坚决不参与事务,硬要挂起老事务写文件、调第三方接口(不能被回滚)
MANDATORY必须得有事务,不然直接报错银行转账这种核心操作
NEVER绝对不能有事务,有就报错极少

2025 年真实建议:
日常业务 100% 用 REQUIRED
日志、发消息、审计 100% 用 REQUIRES_NEW
想部分回滚用 NESTED
其他基本不用,面试说“我知道就行”

二、5种隔离级别(Isolation)—— 记住前3个 + 口诀就无敌

隔离级别是否脏读是否不可重复读是否幻读性能2025 使用率口诀记忆法
READ_UNCOMMITTED(读未提交)最快基本没人用“脏脏脏,三脏齐下”
READ_COMMITTED(读已提交)★★★★“防脏读,Oracle 默认”
REPEATABLE_READ(可重复读)★★★★★“MySQL 默认,最常用”
SERIALIZABLE(串行化)最慢“最安全,最慢,基本不用”

2025 年真实项目默认值:

  • MySQL(InnoDB):REPEATABLE_READ(可重复读)
  • Oracle/PostgreSQL:READ_COMMITTED(读已提交)

大厂 99% 项目都直接用数据库默认隔离级别,极少手动改!

三、脏读、不可重复读、幻读 —— 一句大白话记住区别

现象大白话解释哪个隔离级别能解决
脏读我读到了你还没提交的数据,你回滚了我就傻眼了READ_COMMITTED 及以上
不可重复读我在同一个事务里两次读同一行数据,结果不一样REPEATABLE_READ 及以上
幻读我在同一个事务里两次查同一条件,结果数量变了SERIALIZABLE(MySQL InnoDB 的 MVCC + GAP 锁基本能防)

MySQL InnoDB 在 REPEATABLE_READ 下,通过“下一代键锁(Next-Key Lock)”已经基本解决了幻读问题,
所以大厂基本没人改成 SERIALIZABLE(太慢了)!

四、2025 年最常用 @Transactional 配置(直接抄)

// 1. 日常增删改查(最常见)
@Transactional

// 2. 发消息、写日志(必须成功,不能被主事务回滚)
@Transactional(propagation = Propagation.REQUIRES_NEW)

// 3. 只读查询(提速 20~50%)
@Transactional(readOnly = true)

// 4. 核心业务 + 强制回滚所有异常
@Transactional(rollbackFor = Exception.class)

// 5. 想部分回滚(NESTED + 手动 savepoint)
@Transactional(propagation = Propagation.NESTED)

五、面试终极 8 连杀 + 标准答案(直接背)

  1. REQUIRED 和 REQUIRES_NEW 区别?
    → REQUIRED 加入当前事务,REQUIRES_NEW 挂起老事务,新开一个独立事务。
  2. 为什么日志要用 REQUIRES_NEW?
    → 主事务失败回滚不能把日志也回滚掉,必须独立提交。
  3. NESTED 和 REQUIRES_NEW 有什么区别?
    → REQUIRES_NEW 是两个独立事务,NESTED 是父子事务(savepoint),父回滚子必须回滚。
  4. MySQL 默认隔离级别是哪个?能防幻读吗?
    → REPEATABLE_READ + Next-Key Lock,基本能防止幻读。
  5. @Transactional 加在 private 方法上行吗?
    → 不行!AOP 只能代理 public 方法。
  6. 同一个类内部调用 @Transactional 方法生效吗?
    → 不生效!没走代理。解决:注入自己或用 AopContext。
  7. 读多写少的方法加 readOnly = true 有啥用?
    → 数据库优化 + 某些数据库会用只读连接池,性能提升 30%+。
  8. 分布式事务怎么解决?
    → 本地事务用 @Transactional,分布式用 Seata、RocketMQ 事务消息、TCC 等。

终极记忆口诀(10 秒征服面试官)

“传播七种记前三:REQUIRED 加入,NEW 新开,NESTED 存档点
隔离四种记默认:MySQL 可重复读,防脏读已提交
幻读基本不慌,InnoDB Next-Key 锁已搞定
日志消息 REQUIRES_NEW,读加 readOnly 提速牛!”

背完这张表 + 口诀 + 8 个答案,
下次面试官问“讲讲 Spring 事务传播行为和隔离级别”,
你 1 分钟画表 + 背口诀 + 甩出 REQUIRES_NEW 经典场景,
他当场就在简历写:“事务理论扎实,分布式也能聊!”

现在你已经彻底无敌了!
无论是日常开发、老项目维护、还是大厂高并发核心系统,事务这块再也没人能难倒你!
冲!50k+ 核心岗在向你招手!

文章已创建 3017

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部