MVCC在重复读和读已提交场景以及幻读的解决

今天玩了下mysql感觉理解又深了一点

相关文章

(40条消息) MySQL可重复读隔离级别能解决幻读吗?_于你与你丶的博客-CSDN博客_mysql的可重复读能解决幻读吗 

目录

首先:重复读和读已提交

 索引失效造成的引伸:

 然后我们聊聊读已提交和重复读

幻读:

MVCC是如何解决幻读的?

当前读作用

 什么是next key lock?

宕机造成的影响


 

首先:重复读和读已提交

流程:1.首先是事务1进行事务开启,然后开启事务2——>2.事务1进行DML操作比如update某行数据——>3.然后切换到事务2,对事务1操作的数据再DML——>4.会发现事务2被阻塞了

总结:当表有索引,事务1对某行数据进行增删改,那么这行数据就会被上锁(行锁),当事务2对这行数据进行增删改就会出现阻塞(事务2操作其他行数据没事)

当表中没有索引,那么事务1对表中数据进行增删改的时候,整个表就会被上锁(也就是我们的表锁),当事务2进行增删改,无论表中是哪条数据都会被阻塞

 事务2的操作:

 索引失效造成的引伸:

当第二个事务并没有操作事务操作的那行数据,而是操作其他数据时,按道理来说是被行锁所约束,所以说我们的事务2操作其他数据是不会被阻塞的,但是如果你是事务2用了!=,like这种造成索引失效——>就会导致阻塞,因为索引失效,那么就变成表锁级别了固然阻塞

 

 然后我们聊聊读已提交和重复读

已提交和重复读其实都解决了脏读,重复读在此基础上解决了不可重复读的问题——>读已提交:事务1提交了后事务2才能读取事务1操作它更新的内容 ——>重复读:除了事务1要提交,事务2如果要读取最新数据也需要提交,不然读取不到最新数据

而不可重复读简单来说就是——>可能出现事务2在读取的时候,其他事务出现修改数据并且提交,那么我select的数据就发生了变化——>可重复读:利用select也要提交才能读取最新数据,防止了其他事务在select时候修改数据;——>(也体现出可重复读的隔离性之强)

幻读:

其实可重复读解决了我们的幻读问题,从引入MVCC就可以知道(MVCC实现了读已提交和可重复读)

什么是幻读:指的是在同一个事务里面连续执行两次相同的sql语句但是得到结果不同(这里指的是数据的行数发送变化,意思是被插入了)

MVCC是如何解决幻读的?

首先MVCC就是解决读写并发的,利用的是一个多版本的概念,引入三个隐藏字段以及undolog——>对数据进行回滚,成一个链式的数据链——>然后还引入了Read view(哪个版本的数据是可见的)

像下面这种,我们就可以用快照读解决幻读问题——>就是利用我们的MVCC历史版本信息(快照)来获取可见数据 

其实像对数据进行修改的操作采用的都是当前读模式(insert/delete/update)

这些都是当前读——>获取最新的快照数据

1、select * from table where ? lock in share mode; (加共享锁)2、select * from table where ? for update; (加排它锁)

当前读作用

(40条消息) 快照读和当前读_是茜茜qianqian呀的博客-CSDN博客_快照读和当前读

在执行这几个操作时会读取最新的记录——>即时是别的事务提交的数据也可以查询到,比如:1.update一条记录,但是这条记录已经在另一个事务中被delete掉了并且commit——>2.这样就会起冲突,所以在update的时候需要知道最新的数据(读取的是最新的数据,并且需要加锁(排他锁或者共享锁)

举个例子,事务1在update后对该数据进行加锁,此时事务B肯定是无法加入新的数据的(因为我们事务A需要保证update数据前后一致),这时候可能会问我update只锁行数据啊(有索引的情况),其实实际上update锁不止锁查询的那几条语句,这样阻止不了insert,有的人会说锁整个表,那这样效率就会很低,我们用的是间隙锁(行锁+范围锁)

 

 什么是next key lock?

next key lock就是一个行锁(record lock)+范围锁(gap lock),比如某一个辅助索引(比如上面的class_id),如果它有1,3,5这几个值,那么当我们使用next key lock的锁住class_id=1的时候,实际上锁住了(-无穷,1],或者锁住class_id=3的时候,实际上锁住的是(1,3],也就是一个左开右闭的区间——>此时别的事务要在这个区间内插入数据,就会被阻塞住 ,这个锁一直到事务提交才会释放

注意:但是对于“唯一索引”,比如主键的索引,next key lock会降级成行锁,而不会锁住一个区间

 因此,如果上面的事务1的update使用的是主键,事务2也使用主键进行插入,那么实际上事务2根本不会被阻塞,可以立即插入并返回。而对于非唯一索引,next key lock则不会降级

宕机造成的影响

当取消自动提交我们两个事务并发,然后事务2在之前是拿到锁的,然后事务2挂掉了,此时事务1begin,然后进行update,发现竟然踏马阻塞了

——>得到结论:当事务拿到锁资源没有提交后,这个锁资源会一直占用,然后宕机后,一直占着

今天还遇到一个情况,我两个并发事务全部阻塞了,经过排查是因为之前的事务因为宕机没有释放锁,后面show了一下,然后全部kill掉了

show processlist

(40条消息) MySQL锁等待问题(ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction)_sunon_的博客-CSDN博客


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部