文章参考:
在数据库中不可重复读和幻读到底应该怎么分?
作者:暖猫Suki、普通熊猫
正好在琢磨这个问题,也被搞得头昏脑涨,不对之处请牛人指正。
脏读、不可重复读、幻读,网上介绍这几个概念的博文很多。天下博文一大抄,都没有说清楚不可重复读和幻读的区别,只有一篇文章略微提到了一点,这里结合我的理解说一下。
其实这三种现象都是并发读写导致的。
个人认为,严格来讲“幻读”可以被称为“不可重复读”的一种特殊情况,没错的。但是从数据库管理的角度来看二者是有区别的。解决“不可重复读”只要加行级锁就可以了。而解决“幻读”则需要加表级锁,或者采用其他更复杂的技术,总之代价要大许多。这是搞数据库的那帮家伙非要把这两者区分开的动机吧。
禁止写时读,避免了“脏读”,对应隔离级别read committed
。
禁止读时写,避免了“不可重复读”,对应隔离级别repeatable read
。
而为了避免“幻读”,干脆把整个表给锁住了,只能是serialize
了。
隔离级别越高,并行度越低,付出的代价越大。
顺便说一下,phantom
这个词是幻影,幽灵的意思,跟“幻读”的现象没有直接关系。很多文章说遇到“幻读”就像出现幻觉一样,个人以为十分牵强。“幻读”就是软件工程中一个很普通的问题,是人类思虑不周全的结果。老外工程师通过禁止读的时候修改解决了“不可重复读”的问题,本以为万事大吉了,谁知又出现了增加导致的不一致,不由感慨:我X真是个phantom。用中国话说,就是真TM见鬼了。国内翻译成了“幻读”,搞得很神秘,逼格很高的样子。
不可重复读是读异常,但幻读则是写异常。
不可重复读是读异常的意思是,如果你不多select几次,你是发现不了你曾经select过的数据行已经被其他人update过了。避免不可重复读主要靠一致性快照。
幻读是写异常的意思是,如果不自己insert一下,你是发现不了其他人已经偷偷insert过相同的数据了。解决幻读主要靠间隙锁。
下一篇:win10打印机拒绝访问解决方法