作者:胡呈清
爱可生 DBA 团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
在网络上看了几篇关于幻读的文章,总有些不对劲的地方,要么是解释过于官方看不懂,要么压根儿就是错的,于是我找到了著名论文 A Critique of ANSI SQL Isolation Levels ,对幻读问题做了归纳和总结,希望能帮助大家真正理解幻读,大纲如下:

什么是幻读
幻读最早由 ANSI SQL-92 的隔离级别定义中提出:
P3 (Phantom): Transaction T1 reads a set of data items satisfying some . Transaction T2 then creates data items that satisfy T1’s and commits. If T1 then repeats its read with the same , it gets a set of data items different from the first read.
翻译一下:
事务 T1 读取一组满足某些 <搜索条件> 的数据。事务 T2 创建了满足 T1 的 <搜索条件> 的数据项并提交。如果 T1 用相同的<搜索条件>再次读取,得到一组不同于第一次读取的数据。这就叫幻读。
举个例子:

如果把 T2 执行的 SQL 换成 update t set a=2 where a>1 and a<5;这也是幻读吗?下面开始答疑。
问题 1:幻读与不可重复读有什么区别?
ANSI 对于不可重复读定义如下:
P2 (Non-repeatable or Fuzzy Read): Transaction T1 reads a data item. Another transaction T2 then modifies or deletes that data item and commits. If T1 then attempts to reread the data item, it receives a modified value or discovers that the data item has been deleted.
注意和幻读定义的两个不同:
- 幻读定义中有 < search condition >
- 幻读定义中 T2 是“创建数据”,不可重复读的定义中 T2 是修改或者删除数据
啥意思呢?
在满足 < search condition > 的范围内,修改和删除数据必定是对已经存在的数据行操作,而创建数据则意味着创建之前这个数据项是不存在的。“创建数据”不仅是 insert,还包括 update。update 把本来不满足谓词范围的数据项更新成满足谓词范围的数据项,比如:谓词范围是 a>1 and a<5,update a=4 where a=6 就是这样的情况。
再直观点讲(个人解读),不可重复读是说读的结果的行数不变或者减少,结果的内容发生变化;而幻读呢,就是读的结果的行数变多了。
举例:
已知T1 执行两个SQL:

最低0.47元/天 解锁文章
10万+

被折叠的 条评论
为什么被折叠?



