MVCC解决幻读

请求各位大佬,MVCC为什么不能避免幻读呢?根据版本号,每次SELECT出来的数据的创建版本号不是都小于当前事务版本号,那怎么还有幻读呢?#笔试题目#
全部评论
你得看看快照读和当前读
7 回复 分享
发布于 2019-08-22 15:54
举个例子,假设说数据库里有一张表一共有3列,第一列是自增主键,隔离级别为RR级别。 原先数据库表里有3条数据 1 1 1 2 2 2 3 3 3 ------- 此时我开启一个事务A,执行一下select * ,然后再开启一个事务B,insert一条 444并commit。 之后再回到事务A,再次执行select *,毫无疑问111222333,符合可重复读。 再然后我执行一条 sql :update 第三列 = 5 之后再select  结果为 1 1 5 2 2 5 3 3 5 4 4 5 -------- 此时发生了幻读,要解决这个问题也很简单,楼上基本说了,就不多解释了。 如有错误麻烦指出。
点赞 回复 分享
发布于 2019-08-22 16:32
select是非锁定读,本来就不会幻读,update这种锁定读才会出现幻读,需要使用间隙锁避免幻读
点赞 回复 分享
发布于 2019-08-22 15:59
RR级别下每个事务会创建一个快照,RR级别默认第一条SQL才创建快照,依据快照中记录的事务的高水位和低水位判断数据是否可见,低于低水位的必然可见,高于高水位的不可见,如果介于两者之间,也处于活动中的事务id的数据不可见,由此解决的,
2 回复 分享
发布于 2019-08-22 16:03
mvcc是快照读,本身就解决了幻读,当前读的情况下,用间隙锁解决了幻读
点赞 回复 分享
发布于 2019-08-22 16:23
mvcc解决的是可重复读问题,next Key lock解决幻读问题
点赞 回复 分享
发布于 2019-08-22 15:55
谁跟你说的每次查出来的数据的版本号都小于当时事务编号的??
点赞 回复 分享
发布于 2019-08-22 15:59
select属于快照读操作,不会出现幻读,只有update、delete这种当前读操作才会出现幻读现象。 幻读的话,我给你举个例子,假如A事务正在查询id<10的所有数据,只存在id为1~7的数据,8、9并不存在,此时B事务向数据库插入id为8的数据,那么事务A就会出现幻读现象,本来是不存在id为8的数据的,但是像出现幻觉一样读取到了,这就是幻读。 解决的办法是加上next-key锁(也就是行锁+gap锁),gap锁会锁着id为8、9的两个位置,阻止事务A读取数据的时候,事务B向数据库插入数据,这样就避免幻读了
4 回复 分享
发布于 2019-08-22 16:31
幻读是会发现多了数据或者少了数据吧
点赞 回复 分享
发布于 2019-08-22 15:49
不能避免幻读??
点赞 回复 分享
发布于 2019-08-22 15:51
不是默认开启了next keylock 已经避免幻读了吗
点赞 回复 分享
发布于 2019-08-22 15:52
可重复读级别下通过间隙锁,应该是能解决幻读的问题
点赞 回复 分享
发布于 2019-08-22 15:54
能避免幻读吧,或者可重复读+间隙锁
点赞 回复 分享
发布于 2019-08-22 15:56
因为mvcc里面的update是当前读?求大佬解释
点赞 回复 分享
发布于 2019-08-22 16:18
可以避免。分快照读,当前读
点赞 回复 分享
发布于 2019-08-22 19:27
mvcc可以解决幻读,因为读取的是一个历史的快照。如果对数据实时性要求高的话,不推荐。
点赞 回复 分享
发布于 2019-08-22 20:31

相关推荐

09-27 14:42
已编辑
浙江大学 Java
未来未临:把浙大放大加粗就行
点赞 评论 收藏
分享
1 33 评论
分享
牛客网
牛客企业服务