当前位置: 首页 > news >正文

MySQL如何解决幻读?

目录

一、什么是幻读?

1.1 幻读的定义

1.2 幻读的示例

1.3 幻读产生的原因?

1.4 读已提交(Read Committed)

1.4.1 确定事务等级

1.4.2 非锁定读取

准备

示例

结论

1.4.3 锁定读取

准备

示例

分析

结论

1.5 可重复读(Repeatable Read)

1.5.1 确定事务等级

1.5.2 非锁定读取

准备

示例

结论

1.5.3 锁定读取

准备

示例

分析

结论

二、怎么解决幻读?

2.1 提高事务隔离等级

2.2 间隙锁(Gap Locking)

三、间隙锁

3.1 定义

3.2 工作原理

无间隙锁

有间隙锁

3.3 间隙锁的类型

范围查询

相等查询

参考资料


一、什么是幻读?

1.1 幻读的定义

幻读(Phantom Read) 是数据库事务中的一种并发问题,指的是在一个事务执行过程中,另一个事务插入、删除或修改了符合查询条件的记录,导致前一个事务读取到不同的数据集,从而产生“幻觉”般的读操作。

1.2 幻读的示例

具体来说,事务A执行过程中,事务B插入或者修改了记录,导致事务A在相同查询条件下读取到的结果发生了改变。

假设有用户表users,包含列username、password、state。

1.事务A,查询所有状态启用的用户

select count(id) from users where state=1;

2.事务B,插入新用户,state=1

insert into users(username, password, state) values('test11', 123456, 1);

3.事务A,再次执行相同的sql

select count(id) from users where state=1;

事务A两次查询,得到了不同的结果。

1.3 幻读产生的原因?

1.对表进行了插入或删除

2.事务隔离等级

幻读(Phantom Read)通常在较低的事务隔离等级中产生(如 读已提交(READ COMMITTED)、可重复读(REPEATABLE READ))。

读已提交(Read Committed):可以读取到已提交的记录,但无法保证查询过程中数据不被改变,因此会发生幻读;

重复读(Repeatable Read):可以保证事务中多次查询的结果一致,但仍然可能出现幻读,因为在非锁定读取时,允许新记录的插入(即事务 A 查询的范围可能会变化)。

两种隔离等级下,产生幻读的情况看下文具体示例。

1.4 读已提交(Read Committed)

1.4.1 确定事务等级

查看当前事务隔离等级

 SELECT @@transaction_isolation;

将事务隔离等级设为【读已提交】

#设置事务隔离等级

SET SESSION TRANSACTION ISOLATION LEVEL {level};

#{level}可选项::

#读未提交: READ UNCOMMITTED·

#读已提交: READ COMMITTED

#可重复读: REPEATABLE READ

#可串行化: SERIALIZABLE

1.4.2 非锁定读取

准备

准备一组数据,进行以下测试:事务A执行查询,事务B插入一条记录,事务A再次执行查询。

示例

1.事务A执行查询

select * from tmp where id>=2;

2.事务B插入数据,并提交

insert into `tmp`(`id`,`value`) values (4, 'dd');

3.事务A再次执行查询

结论

事务A两次查询结果不一致,可以读取到事务B已提交的记录,出现【幻读】

1.4.3 锁定读取

准备

准备一组数据,进行以下测试:事务A执行查询,事务B插入一条记录,事务A再次执行查询。

示例

1.事务A进行锁定读取

select * from tmp where id >= 4 for update;

2.事务B,在间隙插入数据,并提交

insert into `tmp`(`id`,`value`) values (5, 'dd');

3.事务A再次执行查询,两次读取结果不一致,发现间隙并没有锁住

并且事务B插入的行已经落库。

分析

然后我们看MySQL文档解释

意思就是,在【读已提交】隔离等级下,针对锁定读取(共享锁or排它锁)、UPDATE语句和DELETE语句,innodb只锁定索引到的记录,锁定记录的前后都能插入新记录。也就说“间隙”并没有被锁住。

再看【间隙锁】这边的解释,间隙锁在读已提交隔离等级下,在查询和索引扫描被禁用了。

结论

        虽然使用了锁定读取,但读已提交(Read Committed)下,幻读依然存在。

1.5 可重复读(Repeatable Read)

1.5.1 确定事务等级

查看当前事务隔离等级

 SELECT @@transaction_isolation;

1.5.2 非锁定读取

准备

准备一组数据,进行以下测试:事务A执行查询,事务B插入一条记录,事务A再次执行查询。

示例

1.事务A执行查询

select * from tmp where id>=4;

2.事务B插入一条记录, 并commit

insert into `tmp`( `id`, `value` ) values (5, 'dd');

3.事务A再次执行查询

select * from tmp where id>=4;

事务B执行commit后,由于事务隔离等级缘故,事务A再次查询,结果不影响,具备可重复读特性;事务A结束后,再次查询多了一条数据(5, ‘dd’)。

结论

        在可重复读(Repeatable Read)隔离等级下,事务内部具备可重复读特性; 但由于“间隙”并未锁住,非锁定读取会出现“幻读”。

1.5.3 锁定读取

准备

准备一组数据,进行以下测试:事务A执行查询,事务B插入一条记录,事务A再次执行查询。

示例

事务A执行查询

select * from tmp where id>=4 for update;

事务B插入一条记录

insert into `tmp`( `id`, `value` ) values (5, 'dd');

这时,发现插入操作被阻塞了。

分析

我们看一下执行的查询语句

select * from tmp where id>=4 for update;

  1. Id=4 所在的行
  2. Id=4 与 id=6 之间的间隙
  3. Id=6 所在的行
  4. Id=6 之后的间隙

这就意味着,在间隙插入记录会被阻止,直到事务A结束。

共享锁与示例的排它锁相同,都是通过阻止其他会话变更,来避免对当前会话的影响。

UPDATE语句、DELETE语句与锁定读取(Locking Reads)同理,在执行时,会根据使用的查询条件进行加锁:

  1. 相等(=、in):InnoDB只锁定找到的索引记录
  2. 范围(BETWEEN、>、<):InnoDB锁定扫描的索引范围

要注意的是,对于使用唯一索引的语句,完全没必要进行加锁。

注:

我们知道,默认情况下,MySQL是在autocommit开启的状态下运行。开启事务(START TRANSACTION)后,自动提交模式(autocommit)会隐式禁用,所有的纯SELECT语句会被转化成SELECT.....LOCK IN SHARE MODE, 但是如果想要锁住间隙或是锁住索引记录的话,需要显示触发锁定行为。

结论

        在可重复读(Repeatable Read)隔离等级下,针对锁定读取(共享锁or排它锁)、UPDATE语句和DELETE语句,不会出现“幻读”。

二、怎么解决幻读?

2.1 提高事务隔离等级

使用可串行化(Serializable),提事务隔离等级来避免。在可串行化隔离等级下,数据库会对查询和写进行加锁,确保事务的完全顺序执行,但是并发效率低下。

2.2 间隙锁(Gap Locking

间隙锁是加在索引记录之间间隙的锁,又或者是在索引区间第一条记录之前、或最后一条记录之后。

示例:

 select * from users where age between 10 and 30 FOR UPDATE; 

age(10-30)范围内所有现有值之间的间隙都被锁定,防止其他事务将值等于15插入列age中,无论该列中是否已有该值。

三、间隙锁

3.1 定义

        间隙锁(Gap Lock)是一种数据库锁定机制,常见于支持行级锁的数据库(如 MySQL 的 InnoDB 存储引擎)中,主要用于解决并发事务中的“幻读”问题。

3.2 工作原理

假定有数据表

+----+-------+

| id | title |

+----+-------+

|  1 | aa |

|  2 | bb |

|  3 | cc |

+----+-------+

无间隙锁

        事务A查询id > 2 的记录并锁定这条记录,然后事务B插入一条id=4的新纪录,事务A再次查询时会得到不同的结果集。

有间隙锁

        事务A执行查询 id > 2时,这条查询会锁定 id > 2 的记录、所有行之间的间隙。

3.3 间隙锁的类型

范围查询

当事务执行范围查询(如BETWEEN、>、<等)时,数据库会在查询范围内加上间隙锁。

例如:

select * from `tmp` where `id` > 5 for update;

可重复读(Repeatable Read)隔离等级下,可能会锁定 id >5 的所有间隙.

相等查询

当事务执行相等查询(如 = )时,数据库会锁定对应的索引记录。如果索引记录不存在,则会锁定对应的间隙,防止其他事务插入重复的记录。

示例:

+----+-------+

| id | value |

+----+-------+

|  2 | aa    |

|  4 | bb    |

|  6 | cc    |

+----+-------+

事务A, 执行查询, 锁住id=5的间隙

select * from tmp where id=5 for update;

事务B, 尝试在id=5插入数据

insert into `tmp`( `id`, `value` ) values ( 5, 'bb' );

发现事务B,在事务A未结束的情况下,一直被阻塞直至超时

参考资料

MySQL数据库事务隔离等级:The InnoDB Engine: Transaction Isolation Levels

InnoDB一致性非锁定读取:The InnoDB Engine | Consistent Nonlocking Reads

InnoDB幻影行(幻读):The InnoDB Engine | Phantom Rows

InnoDB间隙锁:The InnoDB Engine | Gap locking

相关文章:

MySQL如何解决幻读?

目录 一、什么是幻读&#xff1f; 1.1 幻读的定义 1.2 幻读的示例 1.3 幻读产生的原因&#xff1f; 1.4 读已提交&#xff08;Read Committed&#xff09; 1.4.1 确定事务等级 1.4.2 非锁定读取 准备 示例 结论 1.4.3 锁定读取 准备 示例 分析 结论 1.5 可重复读…...

Javascript_设计模式(二)

什么是迭代器模式?一般用在什么场景? 迭代器模式是一种行为型设计模式&#xff0c;它用于提供一种顺序访问聚合对象中各个元素的方法&#xff0c;而又不暴露该对象的内部表示。通过使用迭代器模式&#xff0c;可以遍历一个聚合对象&#xff0c;而无需关心该对象的内部结构和…...

时间同步服务器

1、时间同步服务&#xff1a;在多台主机协作时&#xff0c;确保时间同步&#xff0c;防止时间不一致造成的故障。 2、时间按同步实现&#xff1a; ntp 、chrony 3、命令&#xff1a;timedatectl timedatectl set-time "2024-02-13 10:41:55" timedatect…...

react+hook+vite项目使用eletron打包成桌面应用+可以热更新

使用Hooks-Admin的架构 Hooks-Admin: &#x1f680;&#x1f680;&#x1f680; Hooks Admin&#xff0c;基于 React18、React-Router V6、React-Hooks、Redux、TypeScript、Vite2、Ant-Design 开源的一套后台管理框架。https://gitee.com/HalseySpicy/Hooks-Adminexe桌面应用…...

STM32 ADC --- DMA乒乓缓存

STM32 ADC — DMA乒乓缓存 文章目录 STM32 ADC --- DMA乒乓缓存软件切换实现乒乓利用DMA双缓冲实现乒乓 通过cubeMX配置生成HAL工程这里使用的是上篇文章&#xff08;STM32 ADC — DMA采样&#xff09;中生成的工程配置 软件切换实现乒乓 cubeMX默认生成的工程中是打开DMA中断…...

SpringCloud基础 入门级 学习SpringCloud 超详细(简单通俗易懂)

Spring Cloud 基础入门级学习 超详细&#xff08;简单通俗易懂&#xff09; 一、SpringCloud核心组件第一代&#xff1a;SpringCloud Netflix组件第二代&#xff1a;SpringCloud Alibaba组件SpringCloud原生组件 二、SpringCloud体系架构图三、理解分布式与集群分布式集群 四、…...

【Windows 常用工具系列 20 -- MobaXterm 登录 WSL】

文章目录 MobaXterm 登录 WSL MobaXterm 登录 WSL 在 WSL 启动之后&#xff0c;打开 MobaXterm&#xff1a; 在 Distribution 中选择自己本地安装的 ubuntu 版本&#xff0c;我这里使用的是ubuntu-20.4&#xff0c;然后在 runmethod 中选择 Localhost connection. 连接成功之…...

【vmware+ubuntu16.04】ROS学习_博物馆仿真克隆ROS-Academy-for-Beginners软件包处理依赖报错问题

首先安装git 进入终端&#xff0c;输入sudo apt-get install git 安装后&#xff0c;创建一个工作空间名为tutorial_ws&#xff0c; 输入 mkdir tutorial_ws#创建工作空间 cd tutorial_ws#进入 mkdir src cd src git clone https://github.com/DroidAITech/ROS-Academy-for-Be…...

UniApp的Vue3版本中H5配置代理的最佳方法

UniApp的Vue3版本中H5项目在本地开发时需要配置跨域请求调试 最开始在 manifest.json中配置 总是报404&#xff0c;无法通过代理请求远程的接口并返回404错误。 经过验证在项目根目录创建 vite.config.js文件 vite.config.js内容: // vite.config.js import {defineConfig }…...

深入了解Pod

Pod是Kubernetes中最小的单元,它由一组、一个或多个容器组成,每个Pod还包含了一个Pause容器,Pause容器是Pod的父容器,主要负责僵尸进程的回收管理,通过Pause容器可以使同一个Pod里面的多个容器共享存储、网络、PID、IPC等。 1、Pod 是由一组紧耦合的容器组成的容器组,当然…...

基于Spider异步爬虫框架+JS动态参数逆向+隧道代理+自定义中间件的猎聘招聘数据爬取

在本篇博客中&#xff0c;我们将介绍如何使用 Scrapy 框架结合 JS 逆向技术、代理服务器和自定义中间件&#xff0c;来爬取猎聘网站的招聘数据。猎聘是一个国内知名的招聘平台&#xff0c;提供了大量的企业招聘信息和职位信息。本项目的目标是抓取指定城市的招聘信息&#xff0…...

Spring 中的 BeanDefinitionParserDelegate 和 NamespaceHandler

一、BeanDefinitionParserDelegate Spring在解析xml文件的时候&#xff0c;在遇到<bean>标签的时候&#xff0c;我们会使用BeanDefinitionParserDelegate对象类解析<bean>标签的内容&#xff0c;包括<bean>标签的多个属性&#xff0c;例如 id name class in…...

BERT模型核心组件详解及其实现

摘要 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种基于Transformer架构的预训练模型&#xff0c;在自然语言处理领域取得了显著的成果。本文详细介绍了BERT模型中的几个关键组件及其实现&#xff0c;包括激活函数、变量初始化…...

图论-代码随想录刷题记录[JAVA]

文章目录 前言深度优先搜索理论基础所有可达路径岛屿数量岛屿最大面积孤岛的总面积沉默孤岛Floyd 算法dijkstra&#xff08;朴素版&#xff09;最小生成树之primkruskal算法 前言 新手小白记录第一次刷代码随想录 1.自用 抽取精简的解题思路 方便复盘 2.代码尽量多加注释 3.记录…...

c#加载shellcode

本地加载bin文件 SharpPELoader项目如下&#xff1a; using System; using System.IO; using System.Runtime.InteropServices;namespace TestShellCode {internal class Program{private const uint MEM_COMMIT 0x1000;private const uint PAGE_EXECUTE_READWRITE 0x40;pr…...

HarmonyOS 开发环境搭建

HarmonyOS&#xff08;鸿蒙操作系统&#xff09;作为一种面向全场景多设备的智能操作系统&#xff0c;正逐渐在市场上崭露头角。为了进入HarmonyOS生态&#xff0c;开发者需要搭建一个高效的开发环境。本文将详细介绍如何搭建HarmonyOS开发环境&#xff0c;特别是如何安装和配置…...

【网络云计算】2024第46周周考-磁盘管理的基础知识-RAID篇

文章目录 1、画出各个RAID的结构图&#xff0c;6句话说明优点和缺点&#xff0c;以及磁盘可用率和坏盘数量&#xff0c;磁盘总的数量2、写出TCP五层模型以及对应的常用协议 【网络云计算】2024第46周周考-磁盘管理的基础知识-RAID篇 1、画出各个RAID的结构图&#xff0c;6句话说…...

深入理解 SQL_MODE 之 ANSI_QUOTES

引言 在 MySQL 数据库中&#xff0c;sql_mode 是一个重要的配置参数&#xff0c;它定义了 MySQL 应该遵循的 SQL 语法标准以及数据验证规则。其中&#xff0c;ANSI_QUOTES 是 sql_mode 中的一个重要选项&#xff0c;它改变了 MySQL 对于字符串和标识符的识别方式&#xff0c;使…...

容器技术在持续集成与持续交付中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 容器技术在持续集成与持续交付中的应用 容器技术在持续集成与持续交付中的应用 容器技术在持续集成与持续交付中的应用 引言 容器…...

【嵌入式软件-STM32】OLED显示屏+调试方法

目录 一、调试方式 1&#xff09;串口调试 优势 弊端 2&#xff09;显示屏调试 优势 弊端 3&#xff09;Keil调试模式 4&#xff09;点灯调试法 5&#xff09;注释调试法 6&#xff09;对照法 二、OLED简介 OLED组件 OLED显示屏 0.96寸OLED模块 OLED外观和种类…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...