MySQL行锁的实践

server/2024/9/24 9:19:11/

在MySQL中,根据加的粒度,可以将数据库细分为表>行、页。其中,表(Table Lock)是一种粗粒度的,它定整个表,阻止其他事务访问表中的任何行;>行(Row Lock)是一种细粒度的,它定指定的行;页(Page Lock)是介于>行和表之间的一种机制,它定表的一个页或多个页。此外,无论是表,还是>行,都可以根据是否独占数据还是共享数据,进一步细分为共享和排他。这里重点介绍下>行,关于表和页可以参考笔者之前的MySQL概述一文。

>行的实现方式

对不同的存储引擎,的支持情况和使用方式是不同的。如MyISAM只支持表级,不支持>行InnoDB默认采用>行,在未使用索引字段查询时升级为表。需要说明的是,即便在条件中使用了索引字段,MySQL会根据自身的执行计划,考虑是否使用索引。如果MySQL认为全表扫描效率更高,即使指定了索引字段,也不会使用索引,这种情况下InnoDB将使用表,而不是>行。因此,在分析冲突时,有必要进一步检查SQL的执行计划,以确认是否真正使用了索引。
InnoDB为实现>行,提供了多种实现方式。如记录(Record Lock)、间隙(Gap Lock)、临键(Next-Key Lock)等。需要说明的是,>行仅在使用索引字段时才会生效,否则会升级为表

记录(Record Lock)

记录是封记录,记录也叫>行,示例如下:

SELECT * FROM `test_table` WHERE `id` = 1 FOR UPDATE;

它会在 id=1 的记录上加上记录,以阻止其他事务插入,更新,删除 id=1 这一行。

间隙(Gap Lock)

间隙定一个范围,但不包含记录本身,间隙是封索引记录中的间隔,或者第一条索引记录之前的范围,又或者最后一条索引记录之后的范围。间隙主要目的,也是为了避免出现幻读(Phantom Read),对应的事务的隔离级别降级为可重复读。如果将事务的隔离性级别调整成读已提交读未提交,间隙都会失效。间隙对应的事务隔离级别是可重复。示例如下:

SELECT * FROM `test_table` WHERE `id` > 100 FOR UPDATE

以下情况均会产生间隙
(1) 使用普通索引,且需要定一个区间。
(2) 使用多列唯一索引,且需要定一个区间。
(3) 使用唯一索引,且需要定一个区间。
注意,间隙的不是多条记录,而是一个区间,以防止出现幻读现象。

临键(Next-Key Lock)

临键,是记录与间隙的组合,它的封范围,既包含索引记录,又包含索引区间。同间隙一样,临键也是为了避免出现幻读(Phantom Read)。同样的,临键对应的事务隔离级别是可重复。示例如下:

SELECT * FROM table WHERE age >=24 FOR UPDATE; 

临键住一段左开右闭区间的数据。需要强调的一点是,InnoDB 中临键只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键

>行的共享或排他

>行支持设置共享模式或排他模式。其中共享模式允许其他事务读操作,不允许其他事务写操作,注意共享模式也不支持当前事务写操作。排他模式不允许其他事务读操作。不允许其他事务写操作。

共享

共享>行的设置如下:

SELECT ... FOR SHARE

多事务并发环境中,通过LOCK IN SHARE MODE可以避免脏读(Dirty Read),即读取到其他事务未提交的数据。
SELECT … FOR SHARE 是 SELECT … LOCK IN SHARE MODE的升级写法,不同的用户应该根据当前的MySQL版本选择合适的写法。注意,MySQL兼容支持LOCK IN SHARE MODE的写法。此外,FOR SHARE支持NOWAIT和, SKIP LOCKED等选项。

排他

排他>行的设置如下:

SELECT ... FOR UPDATE

共享适用于那些需要确保读取的数据在事务期间不被修改,但允许其他事务并发读取的场景,排他则适用于需要修改数据的场景,确保在修改过程中数据不会被其他事务读取或修改。

>行的释放

无论是SHARE模式,还是UPDATE模式的>行,都是在事务提交(commit)或事务回滚(rollback)的时候释放>行

>行的等待

默认情况下,对于没有获得>行的事务需要一直等待>行的释放,这样可能会影响其他事务的执行。一种有效的处理方式是设置的等待策略。如指定等待时间、不等待、跳过定的数据等。MySQL不支持等待指定的时间(国产数据库OceanBase则支持设置>行的等待时间,示例如下:SELECT … FOR UPDATE WAIT seconds),但支持设置不等待、跳过定的数据。示例语句如下:

SELECT ... FOR UPDATE NOWAIT
SELECT ... FOR UPDATE SKIP LOCKED

注意,以上能力是在MySQL 8.4版本及之后的版本才引入的功能。在使用的时候,要注意当前使用的MySQL版本。如果是低版本的MySQL,可以考虑在应用层做一些简单地处理。

>行的超时时间

在MySQL中,不支持针对每个>行实例设置超时时间,但是支持对所有的>行设置超时时间,对应的参数是innodb_lock_wait_timeout。这个参数决定了InnoDB在放弃获取之前等待的时间长度(以秒为单位)。如果在指定的时间内无法获取,需要获取的事务将被回滚,并返回一个错误。innodb_lock_wait_timeout 的默认值取决于 MySQL 版本。通常,默认值是 50 秒。 >行的超时设置示例如下:

// 全局设置
SET GLOBAL innodb_lock_wait_timeout = 30; -- 设置全局的超时时间为 30 秒
// Session设置
SET SESSION innodb_lock_wait_timeout = 30; -- 设置当前会话的超时时间为 30 秒

这样的话,如果在指定时间范围内无法获取,获取的事务将返回一个错误,提示等待超时。

>行使用总结

>行的使用场景,主要是用于需要实现细粒度控制的场景,如高并发场景。InnoDB为提供了多种>行的实现方式,如记录(Record Lock)、间隙(Gap Lock)、临键(Next-Key Lock)等。需要说明的是,>行仅在使用索引字段时才会生效,否则会升级为表
在使用>行时,支持设置共享模式或排他模式。其中共享模式允许其他事务读操作,不允许其他事务写操作,注意共享模式也不支持当前事务写操作。排他模式不允许其他事务读操作,不允许其他事务写操作。
>行的释放,都是在事务提交(commit)或事务回滚(rollback)的时候。
默认情况下,对于没有获得>行的事务需要一直等待>行的释放,这样可能会影响其他事务的执行。MySQL支持设置不等待(NOWAIT)、跳过定的数据(SKIP LOCKED)等选项来处理等待的情况。注意,上述设置仅在MySQL 8.4及更高版本才支持。
此外,可以为>行设置超时时间。注意,MySQL不支持针对每个>行实例设置超时时间,仅支持对所有的>行设置超时时间,对应的参数是innodb_lock_wait_timeout。innodb_lock_wait_timeout 的默认值取决于 MySQL 版本。通常,默认值是 50 秒。这样的话,如果在指定时间范围内无法获取,获取的事务将返回一个错误,提示等待超时。

参考

https://blog.csdn.net/winy_lm/article/details/48175885 oracle for update和for update nowait的区别
https://docs.pingcode.com/baike/2033002 mysql数据库如何加>行
https://dev.mysql.com/doc/refman/8.4/en/innodb-locking-reads.html Locking Reads
https://yiyan.baidu.com 文心一言


http://www.ppmy.cn/server/119128.html

相关文章

使用 Elastic 和 LM Studio 的 Herding Llama 3.1

作者:来自 Elastic Charles Davison, Julian Khalifa 最新的 LM Studio 0.3 更新使 Elastic 的安全 AI Assistant 能够更轻松、更快速地与 LM Studio 托管模型一起运行。在这篇博客中,Elastic 和 LM Studio 团队将向你展示如何在几分钟内开始使用。如果你…

【系统架构设计师】单例模式(Singleton Pattern)

单例模式详解 1. 什么是单例模式? 单例模式(Singleton Pattern)是一种创建型设计模式,它的目的是确保一个类只有一个实例,并且为整个系统提供一个全局访问点。换句话说,单例模式会限制类的实例化次数,使得在整个应用程序运行期间,类只有一个对象实例。无论何时何地访…

Oracle EBS中AR模块的财务流程概览

应收账款 (AR) 模块是Oracle E-Business Suite (EBS) 中另一个重要的财务管理模块,主要用于管理企业销售过程中的账款回收。下面是AR模块中的一些关键财务流程及其详细说明: 1. 销售订单管理 创建销售订单:当客户下单时,销售人员…

数学建模常用模型---“算法”总结(含特性和应用场景)

目录 数学建模常用模型算法总结1. 代数模型(Algebraic Models)2. 微分方程模型(Differential Equation Models)3. 概率模型(Probabilistic Models)4. 优化模型(Optimization Models)…

http和https分别是什么?区别是什么?

HTTP(超文本传输协议)和HTTPS(安全超文本传输协议)都是用于互联网中传输数据的协议,它们的主要区别在于安全性和数据传输方式。 HTTP(超文本传输协议) 定义:HTTP是一种用于从服务器传…

硬件工程师笔试面试——晶振

目录 13、晶振 13.1 基础 晶振原理图 晶振实物图 13.1.1 概念 13.1.2 工作原理 13.1.3 应用领域 13.1.4 产品类型 13.2 相关问题 13.2.1 晶振的工作原理是什么,它如何保证频率的稳定性? 13.2.2 在工业控制领域,晶振是如何确保精确度的? 13.2.3 晶振的Q值是如何…

EclipseRCP开发(三)-如何去除顽固原生菜单项

去除new-project及other菜单 获取所有菜单项,筛选出new菜单,将new菜单清空,再重新从已注册的向导中添加所需菜单。记录之。 if ("new".equals(ii.getId())) {MenuManager newMenu (MenuManager) ii;// 清除现有的所有子项newMenu.…

切换淘宝最新镜像源:优化NPM包管理的极致体验

在NPM生态系统中,快速、安全地获取所需的包是每个前端工程师追求的目标。然而,由于不同地区的网络环境,直接通过官方NPM仓库获取包可能会导致下载速度缓慢、超时等问题。针对这些情况,淘宝团队提供了优秀的NPM镜像源,并…