数据库脏读、幻读以及不可重复读

本文深入探讨了数据库事务处理中的脏读、不可重复读及幻读现象,通过生动的例子解释了这些概念,并提供了不同隔离级别的解决方案,帮助读者理解并解决数据库并发操作带来的问题。

最近刷面经,刷到一些这样的面试题,就做一点笔记来加深自己的理解
1、数据库脏读
所谓的脏读顾名思义就是数据被污染了,当数据库存在多个用户时,A对数据进行了修改,但没有确认,但是这时候B对这个数据进行查询,接着A对数据进行了回滚,那样B得到的数据就是一个错误的数据,举个贴近生活的例子,教务系统你的高数老师登记你的高数成绩看走眼了,就把小C的成绩看成你的成绩了,然后你就挂了,然后你查到了该成绩,然后就准备补考,然后老师复查的时候发现登记错误了,就改回来了,然后第二年你补考的时候发现补考名单里面没有你的名字。这就是脏读的原理
2、数据库的不可重复读
数据库不可重复读,所谓的不可重复读,我觉得名字有点歧义,更确切的就是产生了前后矛盾,不可重复读指的是在A查询数据,然后B事件在逻辑中改变了该数据,接着A再对该数据进行查询,出现了前后矛盾。按照上述例子说法就是,你在第一次查询成绩后,老师发现这次题出的太难了,然后给你的分数加了个权重(声明我没有在黑浙江高考),然后第二次你查询成绩你就彻底懵逼了。
3、数据库的幻读
幻读的重点也在于前后数据不对应,事务A首先根据条件索引得到若干数据,然后事务B改变了符合事务A搜索条件的数据,导致事务A再次搜索发现有数据数量不符合。幻读和不可重复读最大的区别在于是不是进行了搜索。也就是保研的时候本来只算必修课,然后我将自己的必修成绩加了起来,然后教务处一纸文件表示选修课也要算成绩,然后。。。
下面说一下解决方案:
脏读最容易解决,只要保证一个事务不会读到另一个并行事务已修改但未提交的数据就可以解决
不可重复读可以通过保证一个事务不会读到另一个并行事务读取但未提交的数据就可以解决
幻读比较麻烦一些必须通过保证事务串行执行

最后补一个事件隔离级别。
Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;

2、REPEATABLE READ(重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

3、READ COMMITTED (提交读):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。

4、Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。

### 、可重复不可重复的概念及区别 #### 1. (Dirty Read) 是指一个事务取了另一个事务未提交的数据。这种情况会导致取到的数据可能是无效的或错误的,因为另一个事务可能会回滚其更改。在 SQL 标准中,`READ UNCOMMITTED` 隔离级别允许[^1]。 #### 2. 不可重复 (Non-Repeatable Read) 不可重复是指在一个事务内多次取同一数据时,由于其他事务对该数据进行了修改并提交,导致取结果不一致。这种问题在 `READ COMMITTED` 隔离级别下可能发生,因为它虽然防止了,但不能保证多次取的一致性[^2]。 #### 3. (Phantom Read) 是指一个事务在执行相同查询时,由于其他事务插入或删除了数据,导致两次查询的结果集不同。不可重复的区别在于,涉及的是新插入或删除的行,而不是现有行的修改。在 `REPEATABLE READ` 隔离级别下,虽然解决了不可重复问题,但仍可能出现[^3]。 #### 4. 可重复 (Repeatable Read) 可重复是指在一个事务内多次取同一数据时,结果始终保持一致。这是因为在该隔离级别下,事务开始后取的数据会被锁定,防止其他事务对其进行修改。`REPEATABLE READ` 解决了不可重复问题,但在某些情况下仍可能遇到[^4]。 ### 数据库事务隔离级别 SQL 标准定义了四种隔离级别,每种级别解决不同的事务隔离问题: 1. **READ UNCOMMITTED**:最低的隔离级别,允许不可重复。 2. **READ COMMITTED**:解决了问题,但仍可能出现不可重复。 3. **REPEATABLE READ**:解决了不可重复问题,但仍可能出现。 4. **SERIALIZABLE**:最高的隔离级别,解决了不可重复问题,但性能开销较大。 ### 示例代码 以下是一个简单的事务隔离级别设置示例(以 MySQL 为例): ```sql -- 设置事务隔离级别为 REPEATABLE READ SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 开始事务 START TRANSACTION; -- 查询数据 SELECT * FROM table_name WHERE condition; -- 提交事务 COMMIT; ``` ### 锁机制 InnoDB 存储引擎通过锁机制实现事务隔离。常见的锁类型包括共享锁(S锁)和排他锁(X锁)。共享锁允许其他事务取被锁行,但禁止修改;排他锁则禁止其他事务取或修改被锁行。此外,InnoDB 的行级锁依赖于索引,若无索引可用,则会退化为表级锁,影响并发性能[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值