计算机专业知识【数据库读操作:不可重复读、脏读及其他现象解析】

embedded/2025/2/24 15:37:39/

在数据库的并发操作场景中,不同的读操作方式会引发不同的数据读取问题。理解这些问题对于确保数据库数据的一致性和准确性至关重要。下面我们将详细介绍数据库中常见的几种读问题,包括不可重复读、脏读等。

一、基本概念:事务与并发控制

在深入了解各种读问题之前,我们需要先明确事务和并发控制的概念。事务是数据库中一组不可分割的操作序列,要么全部执行成功,要么全部不执行。而并发控制则是为了保证多个事务在并发执行时不会相互干扰,确保数据的一致性和完整性。

二、脏读(Dirty Read)

2.1 定义

脏读是指一个事务读取了另一个未提交事务修改的数据。也就是说,事务 A 对数据进行了修改,但还没有提交,此时事务 B 读取了 A 修改后的数据。如果事务 A 后来因为某种原因(如出现错误)回滚了,那么事务 B 读取到的数据就是无效的、“脏”的数据。

2.2 示例

假设数据库中有一个账户表 accounts,其中有一条记录表示用户张三的账户余额为 1000 元。

-- 事务 A 开始
START TRANSACTION;
-- 事务 A 将张三的账户余额减少 500 元
UPDATE accounts SET balance = balance - 500 WHERE user_name = '张三';

此时,事务 A 还未提交。

-- 事务 B 开始
START TRANSACTION;
-- 事务 B 读取张三的账户余额
SELECT balance FROM accounts WHERE user_name = '张三';

事务 B 读取到的余额是 500 元,但如果事务 A 回滚了:

-- 事务 A 回滚
ROLLBACK;

那么张三的实际余额仍然是 1000 元,事务 B 读取到的 500 元就是脏数据。

2.3 影响

脏读可能会导致数据的不一致性和错误的决策。例如,在上述例子中,如果事务 B 基于读取到的 500 元余额进行后续的业务操作(如判断是否可以进行一笔新的转账),就可能会做出错误的决策。

三、不可重复读(Non - Repeatable Read)

3.1 定义

不可重复读是指在同一个事务中,多次读取同一数据时,得到的结果不一致。这通常是因为在事务执行过程中,另一个事务对该数据进行了修改并提交。

3.2 示例

同样以账户表 accounts 为例,事务 A 要对张三的账户余额进行两次查询:

-- 事务 A 开始
START TRANSACTION;
-- 第一次查询张三的账户余额
SELECT balance FROM accounts WHERE user_name = '张三';

假设第一次查询得到的余额是 1000 元。
此时,事务 B 对张三的账户余额进行了修改并提交:

-- 事务 B 开始
START TRANSACTION;
-- 事务 B 将张三的账户余额增加 200 元
UPDATE accounts SET balance = balance + 200 WHERE user_name = '张三';
-- 事务 B 提交
COMMIT;

然后,事务 A 再次查询张三的账户余额:

-- 事务 A 第二次查询张三的账户余额
SELECT balance FROM accounts WHERE user_name = '张三';

这次查询得到的余额是 1200 元,与第一次查询的结果不一致,这就是不可重复读的情况。

3.3 影响

不可重复读可能会影响事务的一致性和准确性。例如,在一个统计报表生成的事务中,如果在事务执行过程中出现了不可重复读的情况,那么生成的报表数据可能会不准确,从而影响决策的正确性。

四、幻读(Phantom Read)

4.1 定义

幻读是指在一个事务中,当按照一定条件查询数据时,由于另一个事务插入或删除了符合该条件的数据,导致在该事务的后续查询中出现了之前没有的记录(幻像)或者之前存在的记录消失了。

4.2 示例

假设数据库中有一个订单表 orders,事务 A 要统计所有金额大于 1000 元的订单数量:

-- 事务 A 开始
START TRANSACTION;
-- 第一次统计金额大于 1000 元的订单数量
SELECT COUNT(*) FROM orders WHERE amount > 1000;

假设第一次统计得到的数量是 10 条。
此时,事务 B 插入了一条金额大于 1000 元的订单记录并提交:

-- 事务 B 开始
START TRANSACTION;
-- 事务 B 插入一条金额大于 1000 元的订单记录
INSERT INTO orders (order_id, amount) VALUES (11, 1500);
-- 事务 B 提交
COMMIT;

然后,事务 A 再次统计金额大于 1000 元的订单数量:

-- 事务 A 第二次统计金额大于 1000 元的订单数量
SELECT COUNT(*) FROM orders WHERE amount > 1000;

这次统计得到的数量是 11 条,与第一次统计的结果不同,就好像出现了一个“幻像”订单,这就是幻读的情况。

4.3 影响

幻读可能会导致事务的逻辑出现错误。例如,在一个库存管理系统中,如果一个事务在查询可用库存数量后,另一个事务插入了新的库存记录,那么原事务后续的操作(如根据查询到的库存数量进行发货)可能会出现错误。

五、解决方法

为了避免上述读问题,数据库通常提供了不同的隔离级别,常见的隔离级别有:

  • 读未提交(Read Uncommitted):允许脏读,可能会出现不可重复读和幻读。
  • 读已提交(Read Committed):避免了脏读,但可能会出现不可重复读和幻读。
  • 可重复读(Repeatable Read):避免了脏读和不可重复读,但可能会出现幻读。例如,MySQL 的 InnoDB 存储引擎默认的隔离级别就是可重复读。
  • 串行化(Serializable):最高的隔离级别,避免了脏读、不可重复读和幻读,但会降低并发性能,因为事务是串行执行的。

不同的应用场景可以根据对数据一致性和并发性能的需求选择合适的隔离级别。


http://www.ppmy.cn/embedded/164851.html

相关文章

C/C++跳动的爱心

系列文章 序号直达链接1C/C李峋同款跳动的爱心2C/C跳动的爱心3C/C经典爱心4C/C满屏飘字5C/C大雪纷飞6C/C炫酷烟花7C/C黑客帝国同款字母雨8C/C樱花树9C/C奥特曼10C/C精美圣诞树11C/C俄罗斯方块小游戏12C/C贪吃蛇小游戏13C/C孤单又灿烂的神14C/C闪烁的爱心15C/C哆啦A梦16C/C简单…

第1章:LangChain4j的聊天与语言模型

LangChain4J官方文档翻译与解析 目标文档路径: https://docs.langchain4j.dev/tutorials/chat-and-language-models/ 语言模型的两种API类型 LangChain4j支持两种语言模型(LLM)的API: LanguageModel:这种API非常简单,…

k2路由器登录校园网

教程1刷入Breed,并手动刷入Padavan固件:斐讯K1、K2、K2P 刷机、刷入Breed 辅助工具 | tb (tbvv.net) Padavan下载网址: 我用的是: Padavan 登录的网址是 192.168.123.1 Padavan配置教程: 先用网线连上校园网&#…

SQL ①-数据库 || MySQL

这里是Themberfue 数据库 ✨进入到目前的学习阶段中,数据库相信大家并不陌生,但是如果要说出概念的话那可能还是有点困难的,这里我就简单罗列出数据的一些相关概念,虽然这部分内容只是理论知识,但是非常重要。 &…

AxiosError: Network Error

不知怎么的,项目还在开发阶段,之前还好好的,玩儿了两天再一打开发现页面无法显示数据了,报错如下: 我以为是后端出问题了,但是后端控制台无报错,又用postman测试了一下,可以获取到数…

3DGS(三维高斯散射)算法原理介绍

3DGS(3D Gaussian Scattering)是一种基于高斯分布的三维场景表示与渲染方法,主要用于高效建模和渲染复杂的三维场景,尤其适用于动态环境或需要实时性能的应用。其核心思想是将三维空间中的物体或体积表示为多个高斯函数的集合&…

springboot和springframework版本依赖关系

springboot和springframework版本依赖关系 springboot版本 springframework版本 发布时间 1.0.x 1.0.0.RELEASE 4.0.3.RELEASE 2014.04 1.0.1.RELEASE 4.0.3.RELEASE 2014.04 1.0.2.RELEASE 4.0.3.RELEASE 2014.04 1.1.x 1.1.0.RELEASE 4.0.5.RELEASE 2014.06…

【python】网页批量转PDF

安装wkhtmltopdf 网站:wkhtmltopdf wkhtmltopdf http://www.baidu.com/ D:website1.pdf 安装pdfkit库 pip install pdfkit 批量转换代码 import os import pdfkit path_wkthmltopdf rE:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe config pdfkit.configu…