可重复读隔离级别-幻读

非唯一索引列num

示例1:

事务1 可重复读&事务手动提交事务2 可重复读&事务手动提交
start transaction;
start transaction;
select * intest where num=5 for update;(结果只有一条)
insert into intest set name=‘teat’, num=5;(此处会阻塞住)
select * intest where num=5 for update;(结果仍只有一条,不会幻读)

可重复读隔离级别中
1、select是快照读,不会出现幻读的情况;
2、select for update 是当前读,会加排他锁,其它事务不能修改,不会出现幻读

示例2:

事务1 可重复读&事务手动提交事务2 可重复读&事务手动提交
start transaction;
start transaction;
update intest set num=6 where id=6;
delete from intest where id=6;(此处会阻塞住)
select * from intest where id=6;(id等于6的记录不会被删除)

可重复读隔离级别中
1、update 会自动加锁,堵塞其它事务,不会出现幻读;

示例3:

事务1 可重复读&事务手动提交事务2 可重复读&事务手动提交
start transaction;
start transaction;
在这里插入图片描述
在这里插入图片描述
delete from intest where id=17;
commit;
update intest set num=88 where id=17;(看下面的查询结果,id=17的记录并没有更新)
在这里插入图片描述
commit;
在这里插入图片描述

由于mvcc的快照的原因,事务2中delete掉id=17的记录提交后,事务1再update这条记录,update是当前读,因此就更新不到被删除的记录;接着再select出数据,显示id=17的记录并没有被删除掉,是因为该条记录的trx_id隐藏列的值还是事务1的事务id,并没有改变,因此仍然可以查出来。
示例4:

事务1 可重复读&事务手动提交事务2 可重复读&事务手动提交
start transaction;
start transaction;
update intest set num=6 where id=6;
delete from intest where id=6;(此处会阻塞住)
select * from intest where id=6;(id等于6的记录不会被删除)

可重复读隔离级别中
1、update 会自动加锁,堵塞其它事务,不会出现幻读;

示例5:

事务1 可重复读&事务手动提交事务2 可重复读&事务手动提交
start transaction;
start transaction;
在这里插入图片描述
在这里插入图片描述
insert into intest set name=‘test123’,num=5;
在这里插入图片描述
在这里插入图片描述
commit;
在这里插入图片描述
update intest set num=19;
在这里插入图片描述

可重复读中
1、可以看到,mvcc并没有完全解决幻读的问题,当事务2插入一条新的数据并提交后,事务1在查询并没有出现新的数据。但是当事务1update intest set num=19;之后在执行查询就出现了新当数据,因此出现了幻读。

事务1之所以会出现“幻读”,是因为先进行了一次快照读(select),读取了历史数据,再进行了一次当前读(update intest set num=19),读取最新数据,这样当然会出现幻读了。

需要注意的是,因为update intest set num=19更新到了示例5中的事务2插入的id=46的数据,所以该示例中的事务1在update intest set num=19后select会查询出事务2插入的数据,也就是幻读。如果事务1的update的操作没有更新到事务2插入的数据,那么select是不会出现幻读的

如果事务中都使用快照读,那么就不会产生幻读现象,但是快照读和当前读混用就会产生幻读。

解决这个幻读的办法:可以在select的时候加上锁,这样其它事务就不能插入数据,这样即使事务1执行update或者insert等当前读操作的语句后也不会有新的数据,因为别的事务更改不了

ReadView并不能阻止事务1执行update或者delete语句来改动这个新插入的记录(由于事务2已经提交,因此改动该条记录并不会造成阻塞),但是这样一来,这条新记录的trx_id隐藏列的值就变成了事务1的事务id。之后事务1再使用普通的select语句去查询这条记录时就可以看到这条记录了.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值