快速理解脏读、不可重复读和幻读

本文深入探讨MySQL InnoDB引擎的事务处理,解析脏读、不可重复读与幻读问题,对比不可重复读与幻读的区别,阐述如何通过锁机制避免这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL的InnoDB引擎是支持事务的,但是并发事务的处理又会带来以下问题:

  • 脏读
  • 不可重复读
  • 幻读

一、脏读

脏读指事务A读取到了事务B更新了但是未提交的数据,然后事务B由于某种错误发生回滚,那么事务A读取到的就是脏数据。

具体的说,一个数据原本是干净的,但是事务B将它进行修改使得其不再干净,此时事务A读取到事务B修改后的数据,也就是脏数据,称为脏读,后来事务B由于良心发现又将数据回滚为最初的样子,而事务A不知道事务B进行了回滚操作,最终事务A读取到的是脏数据,称为脏读。

image-20200904212452020

结论:读取未提交的数据!

二、不可重复读

不可重复读指在数据库访问时,一个事务在前后两次相同的访问中却读到了不同的数据内容。

比如说事务A的执行周期较长,事务A在第一次读取某个数据时,此数据的值为100,读取完成后,事务A又去执行其他的事情,在这个过程中,事务B将这个数据的值修改为200,然后事务A做完其他的事情后,又来读取这个数据的值,发现这个值和第一次所读取的值不相同,这种现象称为不可重复读。

image-20200904212959873

结论:前后多次读取,数据内容不一致!

三、幻读

幻读指的是事务A在查询完记录总数后,事务B执行了新增数据的操作,事务A再次查询记录总数,发现两次查询的结果不一致,平白无故的多了几条记录,这种现象称为幻读。

image-20200904213414876

四、不可重复度和幻读的区别

幻读和不可重复读的本质是一样的,两者都表现为两次读取的结果不一致。但是不可重复读指的是两次读取同一条记录的值不同,而幻读指的是两次读取的记录数量不同。

不可重复读重点在于update和delete,而幻读的重点在于insert。

如果使用锁机制来实现这两种隔离级别,在不可重复读中,事务A第一次读取到数据后,就将这些数据加行锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住新增的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以新增数据并提交,这时事务A就会 发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。

MySQL中的、虚是事务隔离级别中可能出现的不同问题: 1. ****[^1]:发生在并发环境中,一个事务看到另一个事务未提交的数据。如果事务A取到了事务B未提交的更新,然后事务B回滚,那么事务A看到的数据就是错误的。可以通过设置较低的事务隔离级别(如READ UNCOMMITTED)来减少,但会带来数据一致性风险。 2. **虚**,又称为不可重复,是指同一个事务内多次取同一数据可能得到不同的结果,因为在此期间有其他事务对数据进行了修改。这通常是因为事务内部的第二次取遇到了另一个事务的修改。为了解决这个问题,可以使用更高的事务隔离级别(如REPEATABLE READ),它会锁定数据直到事务结束,防止其他事务修改。 3. ****:比虚更严重,即使两次取的是同一数据集,但由于事务间的插入或删除操作,导致新的数据行出现在第一次取之后,看起来像是出现了新的数据。无法通过简单的封锁机制解决,因为它涉及到数据的增删。解决通常需要全局序列化,如采用Serializable隔离级别,或者使用行级锁定技术(如InnoDB的Next-Key Locking)。 这些隔离级别的选择会影响应用程序对于并发数据的一致性可见性的预期。默认情况下,MySQL使用REPEATABLE READ隔离级别,以减少虚的可能性。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值