全书目录

第十八篇:MySQL 完全指南 —— 城市户籍总账宇宙

第十章:隔离级别 —— 多个柜台同时翻总账时,彼此能看到什么

2 分钟 715 字 第 345 / 962 个阅读单元

事务不只是“打包提交”,还涉及并发隔离。

想象有两个户籍窗口同时在翻同一本总账:

  • A 窗口正在修改
  • B 窗口正在查询
  • 两边到底能看到什么

这就是隔离级别要解决的问题。

InnoDB 支持四种经典隔离级别:

隔离级别 户籍总账类比 直觉理解
READ UNCOMMITTED 你连别人还没盖章的草稿都能偷看 最松,可能脏读
READ COMMITTED 只能看已盖章版本,但每翻一次都可能看到新版本 不脏读,但可能不可重复读
REPEATABLE READ 本次办理期间,你一直按第一次看到的账本快照办事 InnoDB 默认级别
SERIALIZABLE 大家尽量像排单队,一个个严肃办理 最严格,并发代价最高

设置会话级隔离级别:

sql
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

然后开始事务:

sql
START TRANSACTION;

要理解 InnoDB 的默认 REPEATABLE READ,你可以先记住一句话:

普通 SELECT 往往读的是一致性快照。

也就是:

  • 不是所有读都会加锁
  • 在一个事务里,普通查询可能持续看到同一份“时间切片”

这正是 InnoDB 并发能力强的重要原因。

但如果你不是单纯“看看”,而是要“看完就改”,就要用锁定读

sql
SELECT *
FROM citizens
WHERE citizen_id = 1
FOR UPDATE;

或者:

sql
SELECT *
FROM citizens
WHERE citizen_id = 1
FOR SHARE;

可以把它理解为:

  • FOR UPDATE:这条档案我先占住,别人别改
  • FOR SHARE:这条档案我先按住,别人先别写

还要知道一个 MySQL/InnoDB 的重点:

REPEATABLE READ 下,InnoDB 不只是管“行”,还会在一些范围场景里用到 gap lock / next-key lock 的思路,避免区间并发写带来更复杂的问题。

你不需要一开始把锁类型全背下来,但要知道:

隔离级别越强,越安全;通常也越容易带来等待和阻塞。