MySQL是如何解决幻读问题

阅读: 评论:0

MySQL是如何解决幻读问题

MySQL是如何解决幻读问题

MySQL默认的隔离级别和其他数据库不一样,它默认的是可重复读(Repeatable-Read),其他大部分数据库是读已提交(Read-Commited),为什么会这样呢?先认识一下隔离级别.

认识隔离级别

各个隔离级别下分别会出现的问题:

隔离级别脏读不可重复读幻读
未提交读可能可能可能
已提交读不可能可能可能
可重复读不可能不可能可能
可串行化不可能不可能不可能

脏读: 事务A读取到了事务B修改但未提交且最后要回滚的数据。
小明去取钱,小红给小明汇钱,小明输入密码后发现金额100, 小明取走50,在小明取走过程中,小红汇钱给小明 50,小红还没有确定汇款,小明这是拿到50块钱后发现余额还是100; 这时这100块是脏读;
不可重复读: 事务A读取到的数据不一致(两次读取之间有事务B做更新操作)
例如:小明取钱,小红去花小明的钱,小明账户余额100,小明取走50,小明取走后50后查询余额是50,小红手机支付10块,小明再查余额变成40了;
幻读: 事务A读取的结果条数不一致(两次读取之间有事务B做插入数据操作)
A把数据一条数据1改成了2,B同时往数据库中插入了一条1,A再查看的时候 发现1还在;

可串行化严重影响并发性能,用的并不多。那么还剩下幻读的问题没有解决

MySQL为什么用可重复读作为默认隔离级别

这要从主从复制说起:
1.主从复制,是基于什么复制的?

是基于binlog复制的

2.binlog有几种格式?

statement:记录的是修改SQL语句

row:记录的是每行实际数据的变更

mixed:statement和row模式的混合

那Mysql在5.0这个版本以前,binlog只支持STATEMENT这种格式!而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,主库和从库因为执行顺序问题,导致数据不一致,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!

如何解决幻读

**MVCC(多版本并发控制):**在高性能MySQL第三版中可重复读隔离级别的描述中写到:可重复读不能避免幻读的产生。幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新行,当之前的事务再次读取该范围的记录时,会产生幻行。InnoDB存储引擎通过多版本并发控制(MVCC)解决了幻读问题。

我们先来看一个可重复读隔离级别(RR)下的实例:

事务/时刻事务A事务B
t1begin;
t2select * from studentbegin;
t3insert into student(…)
t4select * from student

在t4时刻,理论上是不是和t2的查询结果不一致呢,如果是,那就还会产生幻读;
事实上,不会,这是MVCC的功劳。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,在某个时间点事务开启时,其看到的数据是该时间点之前已经提交的数据的快照内容,这就保证了事务执行期间看到的数据时一致的。

本文发布于:2024-01-28 20:14:09,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17064440529993.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:如何解决   MySQL
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23