解决MySQL幻读?可重复读隔离级别背后的工作原理

什么是当前读和快照读

  1. 当前读:又称为 "锁定读",它会读取记录的最新版本(也就是最新的提交结果),并对读取到的数据加锁,其它事务不能修改这些数据,直到当前事务提交或回滚。"select … for update" 和 "update"、"delete"、"insert" 这类修改数据的语句都属于当前读。

  2. 快照读:又称为 "一致性读",它会读取记录在事务开始时的版本,也就是它会读取一个快照。"select" 语句一般就是快照读。

MySQL 可重复读隔离级别(RR)

在MySQL可重复读事务隔离级别下可以解决大部分幻读问题,而不是全部幻读问题。如果一个事务在执行过程中既有快照读又有当前读就会发生幻读问题。

在 MySQL 中,默认的事务隔离级别是 “可重复读(RR)”。
如何查询当前事务隔离级别?

SELECT @@transaction_isolation;

COPY

file

在可重复读(RR)隔离级别下,同一个事务中的快照读取同样的记录时,总是能够得到同样的结果,但是无法防止其他事务在此期间插入新的行(新增数据),这种现象被称为幻读。MySQL RR隔离级别下会使用MVVC和Next-Key Lock来防止幻读。

下面的示例展示了幻读现象:
整体逻辑为:

事务A事务B
开启事务,查询数量大于10的订单,此时只能查到2条记录,因为此时另一个事务还没有进行插入,sql语句:SELECT * FROM trade_order WHERE quantity > 10;快照读) !

file

事务B启动并插入一条数量为30的订单并提交事务。SQL语句:INSERT INTO trade_order (item, quantity) VALUES ('pear', 30); 

file

事务A再次执行查询数量大于10的订单,依然只有2条,因为是快照读。sql语句:SELECT * FROM trade_order WHERE quantity > 10;

file

事务A执行快照读,这时候查询到了3条发生幻读,SQL语句:SELECT * FROM trade_order WHERE quantity > 10 for update;(*当前读) 

file

假设我们有一个包含以下数据的 "trade_order" 表:


CREATE TABLE trade_order (id INT PRIMARY KEY AUTO_INCREMENT,item VARCHAR(100),quantity INT
);
-- 插入3条数据,两条数量大于10,一条小于等于10
INSERT INTO trade_order (item, quantity) VALUES
('apple', 10),
('banana', 20),
('cherry', 15);## 事务SQL执行步骤
注意: SQL在两个命令行窗口下执行,目前Windows Powershell可以很容易安装MySQL客户端,所以可以新建两个PowerShell窗口来执行。
```sql
-- Transaction A
START TRANSACTION;
-- 查询 quantity > 10 的记录。因为是快照读,它会读取该事务开始时的记录快照
SELECT * FROM trade_order WHERE quantity > 10;
-- +----+--------+----------+
-- | id | item   | quantity |
-- +----+--------+----------+
-- | 21 | banana |       20 |
-- | 22 | cherry |       15 |
-- +----+--------+----------+
-- 2 rows in set (0.00 sec)-- Transaction B
START TRANSACTION;
-- 插入一条新的记录,quantity > 10
INSERT INTO trade_order (item, quantity) VALUES ('pear', 30);
COMMIT;-- Transaction A
-- 再次查询 quantity > 10 的记录。因为是快照读,它会读取该事务开始时的记录快照
SELECT * FROM trade_order WHERE quantity > 10;
-- +----+--------+----------+
-- | id | item   | quantity |
-- +----+--------+----------+
-- | 21 | banana |       20 |
-- | 22 | cherry |       15 |
-- +----+--------+----------+
-- 2 rows in set (0.00 sec)-- 再次执行当前读取操作(记录最新的数据,并对这些记录加锁)
SELECT * FROM trade_order WHERE quantity > 10 FOR UPDATE;-- +----+--------+----------+
-- | id | item   | quantity |
-- +----+--------+----------+
-- | 21 | banana |       20 |
-- | 22 | cherry |       15 |
-- | 23 | pear   |       30 |
-- +----+--------+----------+
-- 3 rows in set (3.79 sec)
-- 这就是幻读问题,因为这次查询返回了比之前更多的行。COMMIT;

COPY

所以说,在可重复读隔离级别下,MySQL 通过使用快照读(MVCC,多版本并发控制)确保了在一个事务里多次读取同样的记录能得到一致的结果,但是对于新增的行,即出现在事务开始后的新行,就无法做到一致性读取,这种现象被称为“幻读”。

结语

在大多数情况下,MySQL的可重复读(RR)事务隔离级别为绝大多数业务场景提供了适当的一致性保证,并有效地通过MVCC和Next-Key Locks机制解决了幻读问题。尽管如此,RR隔离级别可能会由于锁机制而导致某些性能问题,特别是在密集型的写操作或高并发场景时。

如果业务需求对数据的实时一致性要求不是特别严格或者你可以在应用层处理这些问题,并且更加关注于系统性能,可以考虑将事务隔离级别降低到读提交(RC)。读提交隔离级别在某些情况下可以提供更高的并发性,因为它只在必要时锁定数据行,以此减少锁争用。但是在你切换到RC隔离级别时你得评估带来的问题:比如:不可重复读和幻读,别到时候应用各种问题。

参考

1. 快分清MySQL当前读、快照读和幻读关系 – FOF编程网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/782243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux课程____shell脚本应用

:一、认识shell 常用解释器 Bash , ksh , csh 登陆后默认使用shell,一般为/bin/bash,不同的指令,运行的环境也不同 二、 编写简单脚本并使用 # vim /frist.sh //编写脚本文件,简单内容 #!/bin/bash …

翻译 《The Old New Thing》 - Why is a registry file called a “hive“?

Why is a registry file called a “hive“?https://devblogs.microsoft.com/oldnewthing/20030808-00/?p42943 为什么注册表文件被称为‘蜂巢’? Raymond Chen 2003年8月8日 分享一个没用的知识: 话说有一位 Windows NT 的开发者十分讨厌蜜蜂。于是&a…

sectigo 单IP证书360元

IP数字证书使用了强大的加密功能,能够有效保护网站和用户数据在传输过程中的安全。由Sectigo颁发的各种数字证书兼容性高,可以支持几乎所有主流浏览器,在用户访问时不会出现“不安全”提示,Sectigo旗下的IP证书可以为只有公网IP地…

HAProxy + Vitess负载均衡

一、环境搭建 Vitess环境搭建: 具体vitess安装不再赘述,主要是需要启动3个vtgate(官方推荐vtgate和vtablet数量一致) 操作: 在vitess/examples/common/scripts目录中,修改vtgate-up.sh文件,…

Python之Opencv教程(4):识别图片中多张人脸

1、识别代码 导入必要的库 import cv2加载人脸识别器 face_detector cv.CascadeClassifier("data//haarcascade_frontalface_alt.xml")这里使用了OpenCV自带的人脸识别分类器,路径为cv2.data.haarcascades ‘haarcascade_frontalface_default.xml’。你…

pytorch | torch.contiguous()方法

torch.contiguous()方法语义上是“连续的”,经常与torch.permute()、torch.transpose()、torch.view()方法一起使用,要理解这样使用的缘由,得从pytorch多维数组的低层存储开始说起: touch.view()方法对张量改变“形状”其实并没有…

Linux-3 yum和vim

目录 本节目标: Linux 软件包管理器 yum 什么是软件包 1.yum是什么?软件包? 2.Linux(centos)的生态 3.yum的相关操作 我怎么知道我应该安装什么软件? 4.yum的本地配置 关于 rzsz 查看软件包 Linux编辑器-vim使用 1.v…

开源知识库平台Raneto--使用Docker部署Raneto

文章目录 一、Raneto介绍1.1 Raneto简介1.2 知识库介绍 二、阿里云环境2.1 环境规划2.2 部署介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Raneto镜像五、部署Raneto知识库平台5.1 创建挂载目录5.2 编辑config.js文件5.…

MySQL InnoDB 之 多版本并发控制(MVCC)

多版本并发控制(MVCC,Multi-Version Concurrency Control)是数据库管理系统中用于提供高并发性和在事务处理中实现隔离级别的一种技术。MVCC 允许系统在不完全锁定数据库资源的情况下,处理多个并发事务,从而提高了数据…

Datacom HCIP笔记-OSPF协议 之二

链路:路由器之间的相连的链路 状态:链路上的参数在某一时刻的状态 单边邻居 one way? 收到对端发来的hello报文,其中没有自己的router id LSA类型: 1类LSA:描述路由器自身加入到ospf进程中的直连链路的状态…

大数据-TXT文本重复行计数工具

支持系统类型:Windows 64位系统 Linux 64位系统 苹果64位系统 硬盘要求:固态硬盘(有效剩余磁盘空间大小最低3倍于大数据文件的大小) 内存要求:最低8G(例如只有几百G数据) 如果处理TB级大数据文…

STM32 软件I2C方式读取AS5600磁编码器获取角度例程

STM32 软件I2C方式读取AS5600磁编码器获取角度例程 🔖本例程使用正点原子例程作为工程模板创建。 📘 硬件电路部分 🌿原理图部分: 🌿PCB布线和电路 ✨注意事项:有些硬件需要I2C上拉,否则检…

校园局域网钓鱼实例

Hello ! 我是"我是小恒不会java" 本文仅作为针对普通同学眼中的网络安全,设计的钓鱼案例也是怎么简陋怎么来 注:本文不会外传代码,后端已停止使用,仅作为学习使用 基本原理 内网主机扫描DNS劫持前端模拟后端…

【2023】kafka入门学习与使用(kafka-2)

目录💻 一、基本介绍1、产生背景2、 消息队列介绍2.1、消息队列的本质作用2.2、消息队列的使用场景2.3、消息队列的两种模式2.4、消息队列选型: 二、kafka组件1、核心组件概念2、架构3、基本使用3.1、消费消息3.2、单播和多播消息的实现 4、主题和分区4.…

大模型与数据分析:探索Text-to-SQL

当今大模型如此火热,作为一名数据同学,持续在关注LLM是如何应用在数据分析中的,也关注到很多公司推出了AI数智助手的产品,比如火山引擎数智平台VeDI—AI助手、 Kyligence Copilot AI数智助理、ThoughtSpot等,通过接入人…

Node.js的Event Loop:六个阶段详解

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

括号生成(回溯+剪枝)

22. 括号生成 - 力扣(LeetCode) 题目描述 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 样例输入 示例 1: 输入:n 3 输出:["((()))&q…

五年前端的面试之旅

哈喽我是树酱,最近整理了下前端面试相关的知识题库,借此分享给各位小伙伴,帮助小伙伴早日拿到钟意的offer! 前言 最近就业市场不景气,跟大环境较差也有关,确实给我们也会带来一定的挑战。在招聘网站投简历的…

python批量转化pdf图片为jpg图片

1.把pdf图片批量转为jpg;需要注意的是,需要先安装poppler这个软件,具体安装教程放在下面代码中了 2.代码 #poppler安装教程参考:https://blog.csdn.net/wy01415/article/details/110257130 #windows上poppler下载链接&#xff1a…

从零开始机器学习(机器学习 监督学习之线性回归 损失函数及可视化 梯度下降 线性回归的平方误差损失函数 lab实验)

文章目录 机器学习定义监督学习之线性回归损失函数及可视化梯度下降线性回归的平方误差损失函数lab实验 机器学习定义 机器学习就是机器通过不断训练数据集从逐渐知道正确的结果 机器学习包括监督学习和非监督学习 监督学习:需要输入数据和结果数据来不断训练学习…