解决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编程网

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python统计分析——灵敏度、特异度和ROC曲线

参考资料:python统计分析【托马斯】 1、灵敏度和特异度 灵敏度:也叫作效能。被检验正确识别出来的阳性结果(病人中有疾病且检验结果是阳性的概率)。 特异度:被检验正确识别出来的阴性结果(病人健康且检验结…

mysqldump备份数据库提示ERROR 1064 (42000): You have an error in your SQL syntax

在dos下备份数据库的时候提示上面的错误信息 1 错误详情 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near mysql-v at line 1错误示例图 2 解决办法 通过查资料…

vue2.0脚手架搭建

vue起步 文档 https://v2.cn.vuejs.org/ {{}} 变量、表达式渲染v-html html模板,渲染htmlv-model 绑定值(双向绑定)v-if 判断v-bind:href"地址" 简写:绑定属性 简写:href:"&qu…

OpenKylin安装Kafka

一、操作系统 openKylin 1.0.1 X86 二、下载安装包 # 安装依赖jdk sudo apt-get update sudo apt-get install default-jdk # 下载kafka mkdir -p /data/software/kafka wget https://archive.apache.org/dist/kafka/2.4.1/kafka_2.13-2.4.1.tgz三、解压安装 # 解压缩Kafka…

腾讯云2核2G服务器优惠价格,61元一年

腾讯云2核2G服务器多少钱一年?轻量服务器61元一年,CVM 2核2G S5服务器313.2元15个月,轻量2核2G3M带宽、40系统盘,云服务器CVM S5实例是2核2G、50G系统盘。腾讯云2核2G服务器优惠活动 txybk.com/go/txy 链接打开如下图:…

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

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

TypeScript编译器tsc的入门指南

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

货物摆放例题——(求n的所有因子+foreach循环+set集合应用)

这里写目录标题 例题引入题目分析解题方法1.暴力求解2.求n的所有的因子foreach循环 3.利用 set集合 参考文章 例题引入 题目分析 - n个都是 V1 的小正方体---》去拼成一个大的长方体---》满足nLWH - 也就是,在小于等于n的所有数中,任取3个数&#xff08…

vitess执行计划缓存 测试

打开执行计划器缓存: sysbench /usr/local/share/sysbench/oltp_write_only.lua --mysql-host127.0.0.1 --mysql-port15306 --mysql-userroot --mysql-password --mysql-dbcustomer --report-interval10 100s sysbench /usr/local/share/sysbench/oltp_read_only.l…

前端三剑客 —— HTML (上)

前端 前端是什么? 把我们的数据以各种方式(如:表格、饼图、柱状图等)呈现给用户,我们就可以称之为前端。 做前端需要的工具? notepad、editplus、notepad、VS code、webstorm等,一般用于前端开…

嵌入式硬件中常见的面试问题与实现

1 01 请列举您知道的电阻、电容、电感品牌(最好包括国内、国外品牌) ▶电阻 美国:AVX、VISHAY威世 日本:KOA兴亚、Kyocera京瓷、muRata村田、Panasonic松下、ROHM罗姆、susumu、TDK 台湾:LIZ丽智、PHYCOM飞元、RALEC旺诠、ROYALOHM厚生、SUPEROHM美隆、TA-I大毅、TMT…

数据结构 - 算法效率|时间复杂度|空间复杂度

目录 1.算法效率 2.时间复杂度 2.1定义 2.2大O渐近表示法 2.3常见时间复杂度计算举例 3.空间复杂度 3.1定义 3.2常见空间复杂度计算举例 1.算法效率 算法的效率常用算法复杂度来衡量,算法复杂度描述了算法在输入数据规模变化时,其运行时间和空间…

路径规划——搜索算法详解(五):Dynamic A Star(D*)算法详解与Matlab代码

昨天休息了一天,今天继续学习搜索算法!前几天已经分别介绍了Dijkstra算法、Floyd算法、RRT算法、A*算法,无独有偶,上述算法都只适用于静态环境下两点规划的场景,但是大部分场景是实时变化的,这对规划算法提…

阿里云4核8G服务器ECS u1实例租用优惠价格955元一年

阿里云4核8G服务器优惠价格955元一年,配置为ECS通用算力型u1实例(ecs.u1-c1m2.xlarge)4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选,CPU采用Intel(R) Xeon(R) Platinum处理器,阿里云活动链接 aliyunfuwuq…

手写红黑树【数据结构】

手写红黑树【数据结构】 前言版权推荐手写红黑树一、理论知识红黑树的特征增加删除 二、手写代码初始-树结点初始-红黑树初始-遍历初始-判断红黑树是否有效查找增加-1.父为黑,直接插入增加-2. 父叔为红,颜色调换增加-3. 父红叔黑,颜色调换&am…

相机标定学习记录

相机标定是计算机视觉和机器视觉领域中的一项基本技术,它的主要目的是通过获取相机的内部参数(内参)和外部参数(外参),以及镜头畸变参数,建立起现实世界中的点与相机成像平面上对应像素点之间准…

WPF中继承ItemsControl子类控件数据模板获取选中属性

需求场景 列表类控件&#xff0c;如 ListBox、ListView、DataGrid等。显示的行数据中&#xff0c;部分内容依靠选中时触发控制&#xff0c;例如选中行时行记录复选&#xff0c;部分列内容控制显隐。 案例源码以ListView 为例。 Xaml 部分 <ListView ItemsSource"{Bi…

【Node.js】图片验证码识别

现在越来越多的网站采取图片验证码&#xff0c;防止机器恶意向服务端发送请求。但是常规的图片验证码也不是非常安全了。有非常多第三方库可以对图片上的数字文字等进行识别。 代码实现 首先安装依赖&#xff1a; npm install node-native-ocrnpm&#xff1a;(node-native-oc…

HCIA网络基础11-静态路由

文章目录 自治系统LAN和广播域路由选择路由表数据包转发最长匹配原则路由优先级路由度量静态路由配置静态路由负载分担路由备份缺省路由 以太网交换机工作在数据链路层&#xff0c;用于在网络内进行数据转发。而企业网络的拓扑结构一般会比较复杂&#xff0c;不同的部门&#x…

Mistral 7B v0.2 基础模型开源,大模型微调实践来了

Mistral AI在3月24日突然发布并开源了 Mistral 7B v0.2模型&#xff0c;有如下几个特点&#xff1a; 和上一代Mistral v0.1版本相比&#xff0c;上下文窗口长度从8k提升到32k&#xff0c;上下文窗口&#xff08;context window&#xff09;是指语言模型在进行预测或生成文本时&…