首页 新闻 搜索 专区 学院

mysql中的锁查询数据问题

0
悬赏园豆:10 [待解决问题]

在用命令行窗口测试mysql中锁的问题,都关闭自动提交。表中有id为6和10的数据,7,8,9是没有的。
1,A窗口 start transaction;
2,A窗口 select * from ppp where id >6 and id <10 for update;
3,B窗口 start transaction;
4,B窗口 insert into 表 values(7,7,'77');无法插入,在等待
5,A窗口 commit; 同时B插入成功,A执行select * from表,无法看到新插入的数据
6,B窗口 commit;执行 select * from表 查询可以看到新插入的数据
7,A窗口执行 select * from表 无法看到新插入的数据,但是数据是插入成功的。
为什么两个都提交,事务结束了,步骤7看不到新插入的数据?
如果在步骤5中A窗口没有select查表,在步骤7中查询数据是可以看到新数据的,这是为什么?

雾林的主页 雾林 | 菜鸟二级 | 园豆:201
提问于:2020-09-16 11:12
< >
分享
所有回答(1)
0

MySQL MVCC支持的情况默认是可重复读, 也就是说读的快照的数据, 故第二次查询还是快照的数据。 但是如果是在commit 之后没有查询, 后面新查询就会开启新的快照,这个快照里面就是有之前插入的数据。

下面是可重复读的说明:
REPEATABLE READ (可重复读)

REPEATABLE READ 解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读(Phantom Read的问题。所谓幻读,指的是当某个事务在该取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row). InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC Mutiversion Concurrency Control)解决了幻读的问题,重点:这里更新范围数据的时候的,如果在另外一个事务中插入了在这个范围内的记录,那么这次更新再提交的时候还是会出现未更新到的问题,故MySQL在这种情况下,还给我们加入了GAP锁(间隙锁)和next-lock锁,需要建立索引哦,保证其他事务不能在你更新的范围内插入数据。

可重复读是MySQL的默认事务隔离级别。

具体了解可以看:https://www.cnblogs.com/jssj/p/13437036.html

加速丨世界 | 园豆:211 (菜鸟二级) | 2020-09-16 15:44

我步骤7是在两个事物都提交后读取的,但是没有读到新数据,这时候已经和快照没关系了呀

支持(0) 反对(0) 雾林 | 园豆:201 (菜鸟二级) | 2020-09-16 16:07

@雾林: 你第5步的select 和 第7 步的select 在同一个事物。

支持(0) 反对(0) 加速丨世界 | 园豆:211 (菜鸟二级) | 2020-09-16 16:09

@雾林: 第5步select 之后加一个commit 第7步就可以查到了

支持(0) 反对(0) 加速丨世界 | 园豆:211 (菜鸟二级) | 2020-09-16 16:11
@加速丨世界: select也是一个事务?但是第五步这个select我都没有开启事务
支持(0) 反对(0) 雾林 | 园豆:201 (菜鸟二级) | 2020-09-16 16:12

@雾林: 是的,不然就不能控制可重复读了, Oracle 默认事务级别就是读已提交。只要其他事务提交了,就能读到。

支持(0) 反对(0) 加速丨世界 | 园豆:211 (菜鸟二级) | 2020-09-16 16:22

@加速丨世界: 我的环隔离级别就是可重复读隔离级别,步骤5读不到是肯定的,但是7应该能读到

支持(0) 反对(0) 雾林 | 园豆:201 (菜鸟二级) | 2020-09-16 16:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册