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还在;
可串行化严重影响并发性能,用的并不多。那么还剩下幻读的问题没有解决
这要从主从复制说起:
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 |
---|---|---|
t1 | begin; | |
t2 | select * from student | begin; |
t3 | insert into student(…) | |
t4 | select * from student |
在t4时刻,理论上是不是和t2的查询结果不一致呢,如果是,那就还会产生幻读;
事实上,不会,这是MVCC的功劳。
MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,在某个时间点事务开启时,其看到的数据是该时间点之前已经提交的数据的快照内容,这就保证了事务执行期间看到的数据时一致的。
本文发布于:2024-01-28 20:14:09,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17064440529993.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |