编程教育资源分享平台

网站首页 > 后端开发 正文

MySQL:由浅入深带你搞懂数据库隔离级别~#互联网

luoriw 2024-04-04 12:47:12 后端开发 7 ℃ 0 评论

数据库隔离级别分为毒已提交、毒未提交、可重复读和串形化四类。不同的隔离级别会带来不同的问题,如脏读、不可重复读和幻读等。根据这张总结表,我们可以先对数据库隔离级别有一个整体的认识。接下来,我们将详细分析每种隔离级别的优缺点。

首先是脏读,脏读指的是当前事务读取到其他事务未提交的数据。例如,在t一、t二两个事务中,t一修改了一个数据,将负二改为一百。此时,t二读取了该数据。如果t一最终并未提交修改,而是撤销了这次修改,那么t二读取的数据就是脏数据,即实际是五十却读到了一百。不可重复读指的是在当前事务多次读取时,读到因其他事务提交而前后不一致的数据。

例如,在t一、t二两个事务中,t二读取了一个数据,此时t一对该数据进行了修改。如果t二再次读取这个数据,那么读取的结果就会与第一次不同,这就是不可重复读。最后是换读,指的是在同一事务中相同查询条件的多次查询读取的数据总量不一致。

t一、t二两个事务,t一读取某个范围的数据,t二在这个范围内插入了新的数据。如果t一再次读取这个范围的数据,那么读取的结果集合就会与第一次不同。此外,不可重复读和换读都是发生在同一个事务中两次查询的结果不同。两者的区别在于一个是对原数据的修改,另一个则是结果发生了变化。

例如,解决不可重复读问题的一种思路是只需要对select的结果进行加锁即可。但即使锁住了查找结果,相同的select语句仍然可能出现不一样的结果。因为其他事务的insert操作可能会插入满足上次select条件的新数据行。尽管原select语句的查询结果行数据不变,但再次查找就可能多出了几行,这就是幻读了。

弄清楚上述问题之后,再回头看这张总结表就清晰了。如果数据库隔离级别设置为独位提交,那么就会产生脏读、不可重复读和幻读等问题。

但由于串形化的隔离级别会限制并发能力,因此数据库一般不会设置为串形化的隔离级别,而是通过其他方式来解决。

例如,对于inodb可重复读的隔离级别,就可以解决不可重复读和换读的问题。先来看不可重复读的解决方法。

比如使用select four update手动对查找操作上锁。但这种方法也存在缺点,那就是会降低性能。这样做可能会导致并发性能低下,有没有方法可以在不影响其他操作的情况下避免不可重复读?当然有。

可以通过建立数据版本来满足不变性和修改性的要求,这样既能保证并发性能,又能避免不可重复读的问题。这种方法可以有效提高并发性能。虽然满足了可重复读的要求,但如果读取的是非实时数据,也会存在隐患,特别是对于对数据时效性要求较高的情况。

这其实就是innodb vvc多版本并发控制的实现思路,多版本并发控制指的是维护一个数据的多个版本,使得读写操作不会冲突。快照读是mysql未实现mvcc模型的其中一种非阻塞读功能。而相对而言,当前读则是悲观锁的具体实现。mvcc模型在mysql中的具体实现是由三个字段endu日志和review等完成的。

以下是mvcc具体实现过程,感兴趣的同学可以深入研究一下,启用mvcc后,在进行查找操作时,得到的数据不一定是最新值,因此只能使用select for update来确保得到最新值。因此,在不可重复读隔离级别下,快照读不会出现幻读现象,但快照读和当前读同时出现时可能会出现幻读问题。

在innodb中,间隙锁是采用的一种锁机制,就是对锁的一段区间范围上锁,以避免在对应区域插入新数据。关于间隙锁的细节,这里也不做过多介绍,有机会再进行分享,欢迎留言讨论。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表
最新留言