isolation-levels

隔离级别:一张价格表,不是道德表

策略与机制。 隔离级别是契约——承诺一个事务永远不会看到哪些异常景象;mvcc 和锁是底下兑现承诺的机制。档位是按事务选的,不是全库一刀切。

三读异常(标准档位就是拿它们定义的)。脏读:读到别人未提交的数据。不可重复读:同一事务里同一行读两遍,值变了或行没了——一行变了(被人 UPDATE/DELETE)。幻读:同一范围查询跑两遍,行数变了——一片集合变了(有人往范围里 INSERT)。关键分界:幻读的源头是"原本不存在的行",所以盯住已有行本身防不住它。

标准四档(由松到严)。Read Uncommitted:什么都不堵。Read Committed:堵脏读。Repeatable Read:再堵不可重复读;标准文本里幻读还留着。Serializable:全堵——结果必须等同于某种串行执行顺序。

快照时机,才是 RC 与 RR 的真分界。 MVCC 之下,Read Committed 每条语句拍一张新快照——同一条 SELECT 在别人提交后再跑,就看到新世界,于是不可重复读。Repeatable Read 一个事务只拍一张(在第一条读语句时),所有读反复用它。所以 RR 不是"拍两张、结果一致":从头到尾只有一张照片,不一致无从谈起。RC 是很多张,RR 是一张。

冻结快照的限度。 它正好活一个事务:事务结束,下一事务重拍,立刻看到变了的世界。开得久,读数越来越旧,还钉住旧版本不让清理(见 mvcc 的 GC root 效应)。而写会把你拉回现在:RR 事务想改一行、而这行在它快照之后被改过并提交——PostgreSQL 直接把整个事务判死,报序列化错误(could not serialize access due to concurrent update):不许你把写盖在一个你没见过的版本上,应用层整体重试。InnoDB 走另一条路:写用"当前读"——拿该行最新已提交版本并上锁,从那儿接着写。

各家的菜单——数行为,别数名字。 引擎从标准四档里挑,但可以缺席、并档、加菜。MySQL/InnoDB:四名四实,默认 Repeatable Read。PostgreSQL:四名三实——Read Uncommitted 被悄悄按 Read Committed 执行;默认 Read Committed;其 RR 是快照隔离,Serializable 是 SSI(快照 + 冲突检测)。Oracle:只有两档——Read Committed(默认)与 Serializable(实为快照隔离)。SQL Server:四档之外加了两个快照野档(SNAPSHOT、READ_COMMITTED_SNAPSHOT)。最著名的野档是快照隔离本身:比 RR 强(读者无幻读),比 Serializable 弱——它放行 write skew,一种三读异常根本表达不出来的异常。

幻读与索引——两层不许混。 异常是逻辑层的:定义在查询结果上;全表顺序扫第二遍照样扫到新插入的行,与索引无关。索引只在药里出现:InnoDB 的间隙锁/Next-Key 锁锁的是索引记录之间的空隙——"范围"和"空隙"只在有序索引里存在;没有可用索引,它退化成把扫描碰到的一切全锁上,约等于锁全表。PostgreSQL 的 Serializable 记谓词锁(SIREAD);无索引可依时粒度变粗,最粗记到整张表,冲突与误杀随之飙升。两个引擎在 Serializable + 无索引时结论一致:保证永不降级,降级的是并发——PG 表现为重试风暴,InnoDB 表现为排队阻塞。

价格规律。 沿四档往上,保证升、并发严格单调递减——在同一套实现机制内部,这条曲线没有例外。账有三种付法:等(加锁派)、重来(判死重试派)、看旧世界(快照派)。但这条线不是物理定律:更好的机制能把整条前沿往外推——快照派的 RR 就在保证和读并发上同时赢过加锁派的 RC;只是沿任何一条既定曲线走,更严仍然更贵。

为什么不默认 Serializable。 它的成本要么漏进应用层(回滚重试逻辑),要么压在吞吐上(加锁排队)。绝大多数事务是点查点改,RC 完全覆盖,所以默认停在性价比点上,真需要的那几个事务单独提档即可。Read Uncommitted 凭什么活着:近似统计(大盘、粗略计数)要的是快、容得下误差,有时"脏"正是需求本身(看长导入的未提交进度);而且它连读锁都不等,吞吐最高。菜单上每一档都有它划算的场景。

什么时候真的需要 Serializable 语义——业务规则是集合整体的性质、而不是某一行的性质时。(1) 值班"至少留一人":两个医生各查"班上有 2 人",各退出一个,班次归零——每个事务只动了自己那行,集合不变式照样击穿,这就是 write skew,RC/RR 都放行。

read next
about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →