关于幻读
来源:互联网 发布:郭艾伦体测数据 编辑:程序博客网 时间:2024/06/04 04:33
不可重复读
在同一事务中,两次读取同一数据,得到内容不同,侧重点在于数据修改
幻读
同一事务中,用同样的操作读取两次,得到的记录数不相同,幻读的侧重点在于两次读取的纪录数量不一致
不可重复读和幻读在概念上有些交叉,对于不可重复读来说,在同一个事务中,如果读取到的记录数量发生变化,也可以看作是一种不可重复读,同样,对于幻读来说,同一个事务中的读取结果数量一致,但是内容发生了变化,也可以看成是一种不可重复读。
对于mysql,这里讨论一下read committed和repeatable read两个事务隔离级别的不可重复读和幻读:
read committed:
在read committed隔离级别下,存在不可重复读和幻读现象。
起两个事务1和2,1采用快照读读取数据,2修改其中一条满足1查询条件的数据并提交,这时1再快照读一次,就会发现2添加的记录,这就是不可重复读。但如果1采用当前读方式读取数据,由于读取数据的时候会给满足条件的数据加锁,因此,事务2无法修改数据内容,如果单纯从数据内容发生变化这个方面来考虑的话,是不会出现不可重复读的问题的。同时,如果考虑到记录数量增减,由于read committed隔离级别并没有gap锁,所以虽然不能修改采用当前读方式锁定的数据,但是可以在查询条件满足的范围内增加新的数据,这也可以看作是一种不可重复读,但显然这种情况划分到幻读更好。
repeatable read:
在repeatable read隔离级别下,mysql不仅解决了不可重复读,还通过gap锁的引入,解决了幻读的问题。
具体分析与上边类似,只是在repeatable隔离级别下,如果事务2对某些数据作了更新,事务1通过快照读已经不会读取到数据变化,所以repeatable read隔离级别解决了不可重复读的问题。同时由于引入了gap锁,事务2也无法在事务1采用当前读的前提下在事务1的查询条件满足范围内插入新的数据,所以记录数量不会发生变化,也就不存在幻读问题。
当隔离级别是可重复读,且禁用innodb_locks_unsafe_for_binlog的情况下,才可以利用gap锁避免幻读,gap锁是为了保证语句级别binlog的串行化。
总结:
1. 如果仅仅考虑数据内容发生变化来衡量不可重复读,那么只有在read committed隔离级别的快照读中才会出现不可重复读,如果考虑数据数量变化,那么在read committed隔离级别的快照读和当前读中都存在不可重复读现象;
2. read committed隔离级别下,快照读和当前读都会产生幻读现象;
3. repeatable read隔离级别下,只有快照读会产生幻读现象,当前读已经通过gap锁的引入消除了幻读现象。
(何登成大神在博客中将幻读的定义限制在当前读的前提下,个人认为还是幻读和可重复读的具体定义不清晰)
- 关于幻读
- 关于读有感.
- 关于逻辑读
- 关于读博
- 关于如何读代码
- 关于读博士
- 关于如何读代码?
- 关于如何读代码?
- 关于读ruby代码
- 关于逻辑读问题
- 关于如何读代码?
- 关于多线程读文件
- mysql 关于 不可重复读与幻读的解决方案
- 关于
- 关于
- 关于++,--
- 关于#
- 关于。。。
- 昂贵的聘礼
- LeetCode----Happy Number
- Java基本数据类型与四个运算
- txt文件导入数据库的utf-8问题
- AndroidStudio中添加第三库文件的方法
- 关于幻读
- 源码分析:Java堆的创建
- Java平台3个版本:
- 10005---JavaWeb基础--HttpServletRequest
- 奇淫巧技之键盘自动弹出
- OSX10.11 Xcode7安装模拟器需要授权的问题
- 开发小技巧-移除mysql服务
- 栈堆
- UVA 10256 (计算几何 凸包)