您的位置:

脏读和幻读的区别

一、脏读和幻读的定义

在讨论脏读和幻读的区别之前,我们需要先来了解一下这两个概念的定义。

脏读指的是在一个事务中读取了另一个未提交的事务中的数据,而幻读则是指在同一事务多次读取同一范围内的数据时,由于其他事务的修改,导致前后读取的数据不一致。

二、脏读和幻读引起的原因

脏读和幻读的产生都是因为多个事务之间的并发操作。

脏读的产生是因为有一个事务未提交,另一个事务就去读取了其未提交的数据。而幻读则是因为在读取数据时,其他事务对该数据更新或删除,导致前后读取的数据不一致。

三、脏读和幻读的区别

1. 数据内容的不同

脏读产生的数据内容不同于数据库原本的数据内容,它是未提交的数据,可能导致数据的错误和不一致。

而幻读则是在同一事务内前后读取的数据不一致,导致操作的结果与预期不符,但不会像脏读一样导致数据的错误。

2. 锁的不同

为了避免脏读和幻读的出现,数据库采用了锁机制。脏读需要使用“读未提交”的隔离级别,而幻读则需要使用“可重复读”或“串行化”的隔离级别。

3. 操作的对象的不同

脏读主要针对的是数据的单条记录,而幻读则是针对数据的多条记录。

四、示例代码

下面是一个简单的示例,展示了脏读和幻读的不同表现。

-- 建立测试表
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- 事务一:将年龄为18的用户修改为20,但未提交
START TRANSACTION;
UPDATE `test` SET `age` = 20 WHERE `age` = 18;

-- 事务二:读取年龄为18的用户
SELECT * FROM `test` WHERE `age` = 18;

-- 查询结果为空,因为事务一中的数据未提交,无法读取到

-- 事务三:插入一条数据
START TRANSACTION;
INSERT INTO `test` (`name`, `age`) VALUES ('Lucy', 18);

-- 事务四:两次读取数据
START TRANSACTION;
SELECT * FROM `test` WHERE `age` = 18;
SELECT * FROM `test` WHERE `age` = 18;

-- 第一次查询结果为一条数据,第二次查询结果却变成了两条数据,因为事务三中插入了一条数据