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
sobre esta entrada

Una de las entradas de wiki de sijie. La IA en este sitio está anclada en el mismo corpus y responde en la voz de sijie, con citas que vuelven a entradas como esta — responder le cuesta dinero a sijie, así que espera detrás de un código: ingrese código de acceso →

isolation-levels — Sijie Wang