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

MySQL 通过 Next-Key Locking 技术避免幻读问题

MySQL 通过 Next-Key Locking 技术避免幻读问题

在 MySQL 的 InnoDB 引擎中,Next-Key Locking 技术结合了 行锁(Record Lock) 和 间隙锁(Gap Lock),通过锁定记录和间隙,解决了 Repeatable Read 隔离级别下的幻读问题。

Next-Key Locking 是一种结合了记录锁(Record Lock)和间隙锁(Gap Lock)的锁机制,主要用于InnoDB存储引擎以防止幻读(phantom read)和避免死锁。这种锁机制在InnoDB的默认事务隔离级别(可重复读,REPEATABLE READ)下自动启用,而无需显式配置。

使用InnoDB存储引擎:
Next-Key Locking 是 InnoDB 的特性,确保你使用的是 InnoDB 存储引擎。

事务隔离级别:

  • 可重复读(REPEATABLE READ):这是 InnoDB 的默认事务隔离级别,在此级别下会自动使用 Next-Key Locking。
  • 读已提交(READ COMMITTED):在此隔离级别下,Next-Key Locking 不会被使用,而是使用记录锁(Record Lock)。
    你可以通过以下 SQL 语句查看和设置当前会话的事务隔离级别:
sql
-- 查看当前会话的事务隔离级别
SELECT @@SESSION.transaction_isolation;
 
-- 设置当前会话的事务隔离级别为可重复读
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
 
-- 设置全局事务隔离级别为可重复读(对所有新会话生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

显式锁定:
虽然 InnoDB 会自动管理 Next-Key Locking,但在某些高级场景中,你可能希望显式锁定某些记录或间隙。这可以通过使用 SELECT … FOR UPDATE 或 SELECT … LOCK IN SHARE MODE 语句来实现。

sql
-- 显式锁定某些记录,使用Next-Key Locking
START TRANSACTION;
SELECT * FROM your_table WHERE your_condition FOR UPDATE;
-- 执行其他操作
COMMIT;

监控锁:

你可以使用 SHOW ENGINE INNODB STATUS 或 performance_schema 表来监控锁的情况。
sql
SHOW ENGINE INNODB STATUS\G
或者查询 performance_schema.data_locks 和 performance_schema.data_lock_waits 表:

sql
SELECT * FROM performance_schema.data_locks;
SELECT * FROM performance_schema.data_lock_waits;

通过这些步骤,你可以确认 Next-Key Locking 是否在你的 MySQL 环境中被正确使用。在大多数情况下,InnoDB 会自动管理这些锁,你无需手动配置。但是,了解这些机制对于调试和优化数据库性能是非常有帮助的。

什么是 Next-Key Locking?
Next-Key Locking 是一种锁定区间的机制,包含以下两部分:

1、行锁(Record Lock):
锁定精确的数据行,防止其他事务修改该行。
2、间隙锁(Gap Lock):

  • 锁定数据行之间的“间隙”,防止其他事务在这些空隙中插入新数据。
  • 通过锁定查询范围内的记录及其前后间隙,Next-Key Locking 有效避免了幻读现象。

Next-Key Locking 的原理
在 Repeatable Read 隔离级别下,执行范围查询时,InnoDB 会通过 Next-Key Locking 锁定范围内的记录及其相邻间隙。
例如,执行以下 SQL 查询:

SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE; 

假设当前数据如下:

在这里插入图片描述

  • 锁定 age=25 和 age=28 的行(Record Lock)。
  • 锁定 age > 18 到 age < 35 的所有间隙(Gap Lock),阻止插入 age=19 到 age=34 范围内的新数据。

这样可以确保当前事务提交之前,其他事务无法在查询范围内插入、删除或修改数据,从而避免幻读。

Next-Key Locking 的实现机制
1、Record Lock(行锁):
精确锁定某一行,防止修改。
2、Gap Lock(间隙锁):
锁定数据行之间的空隙,防止插入新记录。
3、Next-Key Locking(行锁 + 间隙锁):
同时锁定行和间隙,保证数据一致性。

Next-Key Locking 的使用过程
事务 A
执行范围查询,例如:

SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE; 

InnoDB 锁定范围内的数据行和间隙。

事务 B
尝试插入 age=26 的新记录,但被阻塞。

事务 A
提交或回滚后,事务 B 才能继续。
通过这种方式,Next-Key Locking 有效防止了并发插入导致的幻读问题。

优势与限制
优势
1、解决幻读问题:
保证范围查询结果的一致性。
2、增强数据安全性:
锁定查询范围内的间隙,防止未提交事务的干扰。
限制
1、降低并发性能:
锁粒度较大,可能导致锁竞争。
2、间隙锁开销:
高并发写入场景下,可能影响效率。

使用场景
1、银行系统中的余额查询:
避免用户查询账户余额时插入新的交易记录,确保一致性。
2、电商系统中的订单查询:
防止订单查询期间插入新订单,保证查询结果稳定。

总结
Next-Key Locking 通过结合行锁和间隙锁,锁定查询范围内的数据行及间隙,有效解决了 Repeatable Read 隔离级别下的幻读问题。虽然这种机制增强了数据一致性,但可能降低并发性能,在实际应用中需要权衡使用。


http://www.kler.cn/a/430531.html

相关文章:

  • QML自定义DelayButton(带进度的按钮)样式
  • ROS自学笔记三十:话题消息输出并转换为Excel形式
  • flask后端开发(11):User模型创建+注册页面模板渲染
  • Speckly:基于Speckle文档的RAG智能问答机器人
  • kafka的备份策略:从备份到恢复
  • 爬虫代理服务要怎么挑选?
  • 【JavaEE】多线程(7)
  • python如何与前端交互
  • NFT Insider #158:$SAND 和 LAND 价格反弹
  • 【 C++ 入门基础】 —— 双壁传奇C语言和C++的爱恨情仇
  • PostGIS分区表学习相关
  • LLM学习笔记(18)序列标注任务(测试模型阶段)
  • 基于STM32的机器人手臂控制
  • 【杂记】vLLM多卡推理踩坑记录
  • VB.NET 从入门到精通:开启编程进阶之路
  • 7_计算机网络五层体系结构
  • 方案介绍|CW32L010安全低功耗MCU:驱动高速风筒新力量
  • day10性能测试(2)——Jmeter
  • fastadmin框架同时使用 阿里云oss和阿里云点播
  • CRF(Conditional Random Fields,条件随机场)的输入数据形状通常取决于其应用场景和具体实现
  • java问题解决_idea导入java项目时包名路径报错解决
  • mysql,DBA面试题——2024年12月整理
  • qt之插件编译
  • STM32 中断系统 掌握
  • 【接口自动化测试】一文从3000字从0到1详解接口测试用例设计
  • 在 Ubuntu 20.04 上安装和配置 Redis