面试 | 你说你熟悉MySql,那你就来谈谈InnoDB如何解决幻读的?

 2023-09-18 阅读 20 评论 0

摘要:这是小小本周的第一篇。今天干了啥今天可是周日,一个休息日,对于休息日来说,小小本身也是比较忙碌的,忙碌的小小,耗费的很多的时间,终于倒腾完成了GitChat,一篇GitChat 将会于近日出炉。完工页面好啦,正式开工今日正

这是小小本周的第一篇。

今天干了啥

今天可是周日,一个休息日,对于休息日来说,小小本身也是比较忙碌的,忙碌的小小,耗费的很多的时间,终于倒腾完成了GitChat,一篇GitChat 将会于近日出炉。完工页面

好啦,正式开工今日正文。今日更新面试题文。

脏读,幻读,不可重复读

既然说到幻读了,那么就先说数据库的三大问题,分别是幻读,脏读,不可重复读。

脏读

在数据库中如何避免幻读,所谓的脏读是指一个事物中访问到了另外一个事物中未提交的数据。如下图所示。如果会话2更新age为10,但是在提交之前会话1希望得到age,那么此时获取到的值为更新前的值,或者如果会话2更新了值,但是执行了rollback,此时会话1拿到的值仍然为10,这为脏读。

幻读

一个事物读取2次,得到的记录条数不一致上图很明显的展示了这个情况,由于在会话1之间插入了一个新的值,所以得到的两次数据就不一样了。

不可重复读

一个事物读取同一条记录2次,得到的结果不一致。由于在读取中间变更了数据,所以会话 1 事务查询期间的得到的结果就不一样了。

隔离级别

还需要一点隔离级别的知识。隔离级别分为四种隔离级别。

READ UNCOMMITTED

可以读取未提交的数据,未提交的数据称为脏数据,所以又称脏读。此时:幻读,不可重复读和脏读均允许;

READ COMMITTED

MySQL数据库原理、设计与应用?只能读取已经提交的数据;此时:允许幻读和不可重复读,但不允许脏读,所以RC隔离级别要求解决脏读;

REPEATABLE READ

同一个事务中多次执行同一个select,读取到的数据没有发生改变;此时:允许幻读,但不允许不可重复读和脏读,所以RR隔离级别要求解决不可重复读;

SERIALIZABLE

幻读,不可重复读和脏读都不允许,所以serializable要求解决幻读;

结论

这里先说结果 在REPEATABLE READ隔离级别下,innodb使用MVCC和next-key locks解决幻读,mvcc解决的是普通读,包括快照读引起的幻读,next-key  locks解决的是当前读情况下的幻读。

如何解决

当前读

当前读,指的是加锁的select。和 update,delete语句,在RR的事物隔离级别下,数据库会使用next-key locks来锁住本条记录和索引区间。拿上面的例子来说,在rr的情况下,假设当前使用的是当前读,加锁了读。select * from table where id>3 锁住的就是id=3这条记录以及id>3这个区间范围,锁住索引记录之间的范围,避免范围间插入记录,以避免产生幻影行记录。

普通读

教师面试找关系有用吗,因为普通读,是不会加锁的读,故不会有next-key  locks的使用,解决幻读的手段为MVCC MVCC会给每行元祖加一些辅助字段,记录创建的版本号,和删除版本号。每个事物在启动的时候,都会有一个唯一的版本号,每开启一个事物,事物的版本号递增。在RR下,增删查改是这样的。

SELECT

读取创建版本小于或等于当前事物版本号的,并且删除版本为空或大于当前事物版本号的记录,这样可以保证在读取之前记录是存在的。

INSERT

把当前事物的版本号保存到行的创建版本号。

UPDATE

新插入一行,并以当前事物的版本号作为新行的创建版本号,同时把原记录行的删除版本号设置为当前事物的版本号。

DELETE

把当前事物的版本号保存到行删除的版本号。

举个例子

Mysql面试题。当我插入一条记录,事物id假设为1,记录如下,即,创建版本号就是事物的版本号。如果进行更新,事物id为2.如果把name更新为taotao,原来的元祖deleteversion版本号为这个事物id,并且新增加一条。

如果我删除的话,假设事物为id为3 事物变成了如下

如果我读取的时候,必须要满足两个条件。

  1. 读取创建版本号小于或者等于当前事物版本号,这意味着数据在这个事物之前被创建。

  2. 删除版本为空或者大于当前事物版本号的记录,意味着删除操作在这个事物之后发生。

举个例子。当前数据库的状态。如果事物A的id为10,现在update table set name = “hh” where id > 3 执行这条语句。事物B的id为11.

insert into table values(11, uu);

最后事物A id=10 在此读取

select * from table where id>3

教师面试紧张 过了。根据上述的规则,

读取创建版本好小于等于当前事务的→那么(4,a)(5,b)(4,hh)(5,hh) 删除版本为空或大于当前事务版本号的记录→(4,hh)(5,hh) 如此读取就没有读取到事务B新插入的那行,解决幻读

最后

我是小小,你若不在,我也一直在,你若在,我也一直在,我是小小,我们下期再见。

小明菜市场

面试种类?推荐阅读

● 传记 | 我的大学三年-不以物喜,不以己悲

● 实践 | Centos 7搭建LVS+Keepalived高可用Web服务群集群

● 牛X | 一款比传统数据库快100-1000倍的数据库,认识一下

● 巧用 | 低成本高可用,巧用Redis

教师面试被打断原因,● 探讨 | SpringBoot + MyBatis 多数据源事物问题

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/74600.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息