知识卡片

四种SQL隔离级别与三类读错误的对应关系

结构图卡

内容

完全隔离能得到可串行化的事务——并发执行的结果与按某种顺序依次执行的结果完全相同,能保证正确(虽然不保证具体是哪种顺序的结果)。但完全隔离对灵活性的代价很大,因此SQL标准定义了四种由强到弱的隔离级别,级别越低、允许的不一致读错误越多、并发吞吐率越高。可串行化:最强级别,不允许任何不一致读,结果必然是某个事务发生前或发生后的正确状态之一。可重复读:允许幻读——向集合里新插入的元素,只让读操作的一部分”看见”,导致读的人把不同时间点看到的片段拼接成一个从未真实存在过的总数(如先数7个、别人插入后再数8个、加出15个这种荒谬结果)。读已提交:允许不可重复读——同一个事务里,前后两次读同一份数据,会因为别的事务在中途提交而得到不同结果,且这个较早读到的值之后再也无法重现。读未提交:最弱级别,允许脏读——能读到别的事务里还未提交、甚至最终会被回滚(因而根本不存在)的数据。级别越高越安全,但灵活性和吞吐率越差;实践中不必给所有事务设置统一的隔离级别,而应该逐个审视每个事务具体承担的风险与流量诉求,各自做出正确性与灵活性的权衡。

结构图

flowchart TB
  A["隔离级别(强→弱)"]
  A --> B["可串行化<br/>无任何不一致读"]
  A --> C["可重复读<br/>允许幻读(插入导致的片段拼接错误)"]
  A --> D["读已提交<br/>允许不可重复读(同一事务内两次读结果不同)"]
  A --> E["读未提交<br/>允许脏读(读到未提交甚至会被回滚的数据)"]

参考来源

- 位置:《企业应用架构模式》第一部分"表述"之"第5章 并发"之"5.5.3 减少事务隔离以提高灵活性"(源文件:_epub-src/OEBPS/Text/000037.html) - 结论依据:原文说明"大多数事务系统使用SQL标准中定义的4种隔离级别。可串行化是最强的级别……仅次于可串行化级别的是可重复读,这时允许幻读……下一个级别是读已提交,它允许不可重复读……最低的隔离级别是读未提交,允许脏读",直接支撑本卡结构图。 - 原始内容:如果要保证正确性必须使用可串行化隔离级别。问题是这时系统的灵活性将受到很大的影响,因此要尽量减少串行化以增加系统的吞吐率。