Mysql锁及其分类

news2025/6/7 14:30:11

目录

    • InnoDb锁
      • Shared locks(读锁) 和 Exclusive locks(写锁)
        • Exclusive locks
        • Shared locks
      • Intention Locks(意向锁)
        • 为什么要有意向锁?
      • Record Locks(行锁)
      • Gap Locks(间隙锁)
      • Next-Key Locks
      • Insert Intention Locks(插入意向锁)
      • AUTO-INC Locks
      • Predicate Locks for Spatial Indexes
        • ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
        • ERROR 1062 (23000): Duplicate entry '6' for key 'PRIMARY'
      • 乐观/悲观锁(select for update)

InnoDb锁

innodb lock

Shared locks(读锁) 和 Exclusive locks(写锁)

InnoDB implements standard row-level locking where there are two types of locks, shared (S) locks and exclusive (X) locks.

  • A shared (S) lock permits the transaction that holds the lock to read a row.
  • An exclusive (X) lock permits the transaction that holds the lock to update or delete a row.
Exclusive locks

Exclusive locks protect updates to file resources, both recoverable and non-recoverable. They can be owned by only one transaction at a time. Any transaction that requires an exclusive lock must wait if another task currently owns an exclusive lock or a shared lock against the requested resource.

独占锁保护文件资源(包括可恢复和不可恢复的文件资源)的更新。它们一次只能由一个事务拥有。如果另一个任务当前拥有对所请求资源的独占锁或共享锁,则任何需要对该资源申请独占锁的事务都必须等待。

Shared locks

Shared locks support read integrity. They ensure that a record is not in the process of being updated during a read-only request. Shared locks can also be used to prevent updates of a record between the time that a record is read and the next syncpoint.

共享锁支持读完整性。它们确保在只读请求期间不会更新记录。共享锁还可用于防止在读取记录和下一个同步点之间进行更新操作。

A shared lock on a resource can be owned by several tasks at the same time. However, although several tasks can own shared locks, there are some circumstances in which tasks can be forced to wait for a lock:

资源上的共享锁可以同时由多个任务拥有。 但是,尽管有几个任务可以拥有共享锁,但在某些情况下可以强制任务等待锁:

  • A request for a shared lock must wait if another task currently owns an exclusive lock on the resource.
  • A request for an exclusive lock must wait if other tasks currently own shared locks on this resource.
  • A new request for a shared lock must wait if another task is waiting for an exclusive lock on a resource that already has a shared lock.

即:

  • 如果另一个任务当前拥有资源上的独占锁,则对共享锁的请求必须等待
  • 如果其他任务当前拥有此资源上的共享锁,则必须等待对独占锁的请求
  • 如果另一个任务正在等待已经具有共享锁的资源的独占锁,则对共享锁的新请求必须

在这里插入图片描述

Intention Locks(意向锁)

InnoDB supports multiple granularity locking(多粒度锁) which permits coexistence of row locks and table locks.

Intention locks are table-level locks that indicate which type of lock (shared or exclusive) a transaction requires later for a row in a table. There are two types of intention locks:

  • An intention shared lock (IS) indicates that a transaction intends to set a shared lock on individual rows in a table. 事务T尝试在表t的某些行记录上设置S锁

  • An intention exclusive lock (IX) indicates that a transaction intends to set an exclusive lock on individual rows in a table. 事务T尝试在表t的某些行记录上设置X锁

锁使用规则:

-XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible
为什么要有意向锁?

表级别锁,加锁效率提高;申请意向锁的动作是数据库完成的,就是说,事务A申请一行的行锁的时候,数据库会自动先开始申请表的意向锁,不需要我们程序员使用代码来申请

考虑场景:A事务行锁(锁住一行,只能读,不能写);B事务表锁,如果能加锁成功,那么理论上可以操作每一行,则与A事务有冲突了,B事务必须等待A事务结束再进行操作,那么B事务怎么判断冲突?

  1. 判断表是否已被其他事务用表锁锁表
  2. 判断表中的每一行是否已被行锁锁住。(遍历每一行判断效率太低)

事务A必须先申请表的意向共享锁,成功后再申请一行的行锁。事务B发现表上有意向共享锁,说明表中有些行被共享行锁锁住了;因此,事务B申请表的写锁会被阻塞。

Record Locks(行锁)

A record lock is a lock on an index record. For example, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; prevents any other transaction from inserting, updating, or deleting rows where the value of t.c1 is 10.

Record locks always lock index records, even if a table is defined with no indexes. For such cases, InnoDB creates a hidden clustered index and uses this index for record locking.

单个索引行记录的锁。

Gap Locks(间隙锁)

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record. For example, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; prevents other transactions from inserting a value of 15 into column t.c1, whether or not there was already any such value in the column, because the gaps between all existing values in the range are locked.

A gap might span a single index value, multiple index values, or even be empty.

Gap locks are part of the tradeoff between performance and concurrency, and are used in some transaction isolation levels and not others.

间隙锁,锁定一个范围,但不包括记录本身。GAP锁的目的,是为了防止同一事务的两次当前读,出现幻读的情况。

Next-Key Locks

是InnoDB引擎在可重复读(REPEATABLE READ)隔离级别下默认使用的锁机制,结合行锁(Record Lock)和间隙锁(Gap Lock),防止幻读问题。‌ 它通过锁定索引记录及其前后间隙,确保事务期间其他事务无法在查询范围内插入新数据或修改已有数据

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

InnoDB performs row-level locking in such a way that when it searches or scans a table index, it sets shared or exclusive locks on the index records it encounters. Thus, the row-level locks are actually index-record locks. A next-key lock on an index record also affects the “gap” before that index record. That is, a next-key lock is an index-record lock plus a gap lock on the gap preceding the index record. If one session has a shared or exclusive lock on record R in an index, another session cannot insert a new index record in the gap immediately before R in the index order.

锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。

例如:

root@localhost : test 10:56:15>select * from t;
+------+
| a    |
+------+
|    1 |
|    3 |
|    5 |
|    8 |
|   11 |
+------+
5 rows in set (0.00 sec)

root@localhost : test 10:56:29>select * from t where a = 8 for update;
+------+
| a    |
+------+
|    8 |
+------+
1 row in set (0.00 sec)

该SQL语句锁定的范围是(5,8],下个下个键值范围是(8,11],所以插入5~11之间的值的时候都会被锁定,要求等待。即:插入5,6,7,8,9,10会被锁住。插入非这个范围内的值都正常。

Insert Intention Locks(插入意向锁)

An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.

Insert Intention Locks意为插入意向锁,插入意向锁是Innodb gap锁的一种类型,这种锁表示要以这样一种方式插入:如果多个事务插入到相同的索引间隙中,如果它们不在间隙中的相同位置插入,则无需等待其他事务。比如说有索引记录4和7,有两个事务想要分别插入5,6,在获取插入行上的独占锁之前,每个锁都使用插入意图锁锁定4和7之间的间隙,但是不要互相阻塞,因为行是不冲突的,意向锁的涉及是为了插入的正确和高效。

AUTO-INC Locks

Predicate Locks for Spatial Indexes

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

三个事务都插入相同数据,其中第一个事务进行了回滚,第三个事务报错
在这里插入图片描述

在第一个事务回滚之前,查看事务锁情况
在这里插入图片描述

  • 事务1获得行记录上的排它锁(LOCK_X | LOCK_REC_NOT_GAP)
  • 紧接着事务T2、T3也开始插入记录,请求排它插入意向锁(LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION);但由于发生重复唯一键冲突,各自请求的排它记录锁(LOCK_X | LOCK_REC_NOT_GAP)转成共享记录锁(LOCK_S | LOCK_REC_NOT_GAP)。

T1回滚会释放其获取到到排它锁,T2,T3都要请求排它锁,但是由于X锁与S锁互斥,T2与T3都等待对方释放S锁,于是便产生了死锁

ERROR 1062 (23000): Duplicate entry ‘6’ for key ‘PRIMARY’

在这里插入图片描述
在这里插入图片描述

乐观/悲观锁(select for update)

乐观锁认为一般情况下数据不会造成冲突,所以在数据进行提交更新时才会对数据的冲突与否进行检测。如果没有冲突那就OK;如果出现冲突了,则返回错误信息并让用户决定如何去做。一般就是:1. CAS; 2. 版本控制

悲观锁,正如其名,它指的是对数据被外界(包括当前系统的其它事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排它性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

使用select … for update会把数据给锁住,不过我们需要注意一些锁的级别,MySQL InnoDB默认Row-Level Lock,且只有「明确」地指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ;否则 MySQL 将会执行Table Lock(将整个数据表给锁住)

-悲观锁乐观锁
概念查询时直接锁住记录使得其它事务不能查询,更不能更新提交更新时检查版本或者时间戳是否符合
语法select … for update使用 version 或者 timestamp 进行比较
实现者数据库本身开发者
适用场景并发量大并发量小
类比Javasynchronized关键字CAS 算法

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

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

相关文章

Postgresql源码(146)二进制文件格式分析

相关 Linux函数调用栈的实现原理(X86) 速查 # 查看elf头 readelf -h bin/postgres# 查看Section readelf -S bin/postgres (gdb) info file (gdb) maint info sections# 查看代码段汇编 disassemble 0x48e980 , 0x48e9b0 disassemble main# 查看代码段某…

【设计模式-4.11】行为型——解释器模式

说明:本文介绍行为型设计模式之一的解释器模式 定义 解释器模式(Interpreter Pattern)指给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。解释器模式是一种…

【已解决】MACOS M4 芯片使用 Docker Desktop 工具安装 MICROSOFT SQL SERVER

1. 环境准备 确认 Docker Desktop 配置 确保已安装 Docker Desktop for Mac (Apple Silicon)(版本 ≥ 4.15.0)。开启 Rosetta(默认开启): 打开 Docker Desktop → Settings → General → Virtual Machine Options …

Quipus系统的视频知识库的构建原理及使用

1 原理 VideoRag在LightRag基础上增加了对视频的处理,详细的分析参考LightRag的兄弟项目VideoRag系统分析-CSDN博客。 Quipus的底层的知识库的构建的核心流程与LightRag类似,但在技术栈的选择和处理有所不同。Quipus对于视频的处理实现,与Vi…

web3-去中心化金融深度剖析:DEX、AMM及兑换交易传播如何改变世界

web3-去中心化金融深度剖析:DEX、AMM及兑换交易传播如何改变世界 金融问题 1.个人投资:在不同的时间和可能的情况(状态)下积累财富 2.商业投资:为企业家和企业提供投资生产性活动的资源 目标:跨越时间和…

国芯思辰|SCS5501/5502芯片组打破技术壁垒,重构车载视频传输链路,兼容MAX9295A/MAX96717

在新能源汽车产业高速发展的背景下,电机控制、智能驾驶等系统对高精度信号处理与高速数据传输的需求持续攀升。 针对车载多摄像头与自动驾驶辅助系统对长距离、低误码率、高抗干扰性数据传输的需求,SCS5501串行器与SCS5502解串器芯片组充分利用了MIPI A…

压敏电阻的选型都要考虑哪些因素?同时注意事项都有哪些?

压敏电阻,英文名简称VDR,电子元器件中重要的成员之一,是一种非线性伏安特性的电阻器件,有电阻特性的同时,也拥有其他自身的特性,广泛应用于众多领域。在电源系统、安防系统、浪涌抑制器、电动机保护、汽车电…

用WPDRRC模型,构建企业安全防线

文章目录 前言什么是 WPDRRC 模型预警(Warning)保护(Protection)检测(Detection)响应(Response)恢复(Recovery)反击(Counterattack) W…

使用 Amazon Q Developer CLI 快速搭建各种场景的 Flink 数据同步管道

在 AI 和大数据时代,企业通常需要构建各种数据同步管道。例如,实时数仓实现从数据库到数据仓库或者数据湖的实时复制,为业务部门和决策团队分析提供数据结果和见解;再比如,NoSQL 游戏玩家数据,需要转换为 S…

Linux 里 su 和 sudo 命令这两个有什么不一样?

《小菜狗 Linux 操作系统快速入门笔记》目录: 《小菜狗 Linux 操作系统快速入门笔记》(01.0)文章导航目录【实时更新】 Linux 是一个多用户的操作系统。在 Linux 中,理论上来说,我们可以创建无数个用户,但…

JAVASCRIPT 简化版数据库--智能编程——仙盟创梦IDE

// 数据模型class 仙盟创梦数据DM {constructor(key) {this.key ${STORAGE_PREFIX}${key};this.data this.加载数据();}加载数据() {return JSON.parse(localStorage.getItem(this.key)) || [];}保存() {localStorage.setItem(this.key, JSON.stringify(this.data));}新增(it…

命名管道实现本地通信

目录 命名管道实现通信 命名管道通信头文件 创建命名管道mkfifo 删除命名管道unlink 构造函数 以读方式打开命名管道 以写方式打开命名管道 读操作 写操作 析构函数 服务端 客户端 运行结果 命名管道实现通信 命名管道通信头文件 #pragma#include <iostream> #include &l…

iOS上传应用包错误问题 “Invalid bundle. The “UIInterfaceOrientationPortrait”“

引言 在开发 iOS 应用的整个生命周期中&#xff0c;打包上传到 App Store 是一个至关重要的步骤。每一次提交&#xff0c;Xcode 都会在后台执行一系列严格的校验流程&#xff0c;包括对 Info.plist 配置的检查、架构兼容性的验证、资源完整性的审查等。如果某些关键项配置不当…

猎板厚铜PCB工艺能力如何?

在电子产业向高功率、高集成化狂奔的今天&#xff0c;电路板早已不是沉默的配角。当5G基站、新能源汽车、工业电源等领域对电流承载、散热效率提出严苛要求时&#xff0c;一块能够“扛得住大电流、耐得住高温”的厚铜PCB&#xff0c;正成为决定产品性能的关键拼图。而在这条赛道…

Flutter快速上手,入门教程

目录 一、参考文档 二、准备工作 下载Flutter SDK&#xff1a; 配置环境 解决环境报错 zsh:command not found:flutter 执行【flutter doctor】测试效果 安装Xcode IOS环境 需要安装brew&#xff0c;通过brew安装CocoaPods. 复制命令行&#xff0c;打开终端 分别执行…

算法:前缀和

1.【模版】前缀和 【模板】前缀和_牛客题霸_牛客网 这道题如果使用暴力解法时间复杂度为O(n*m)&#xff0c;会超时&#xff0c;所以要使用前缀和算法。 前缀和->快速求出数组中某一个连续区间的和。 第一步&#xff1a;预处理出一个前缀和数组 dp。 dp[i]表示[1, i] 区间…

DEVICENET转MODBUS TCP网关与AB数据输出模块的高效融合方案研究

在工业自动化领域&#xff0c;多样化的设备通常采用不同的通信协议&#xff0c;这为系统集成带来了显著的挑战。特别是在需要将遵循DeviceNet协议的设备与基于MODBUS TCP协议的系统进行互连时&#xff0c;这一挑战尤为突出。AB数据输出作为一种功能卓越的DeviceNet分布式输入/输…

牛客小白月赛113

前言&#xff1a;这场的E题补的我头皮都发麻了。 A. 2025 题目大意&#xff1a;一个仅有‘-’‘*’组成的字符串&#xff0c;初始有一个sum 1&#xff0c; 从左到右依次遍历字符串&#xff0c;遇到-就让sum--&#xff1b;遇到*就让sum* 2&#xff0c;问sum有没有可能大于等于…

Mac版本Android Studio配置LeetCode插件

第一步&#xff1a;Android Studio里面找到Settings&#xff0c;找到Plugins&#xff0c;在Marketplace里面搜索LeetCode Editor。 第二步&#xff1a;安装对应插件&#xff0c;并在Tools->LeetCode Plugin页面输入帐号和密码。 理论上&#xff0c;应该就可以使用了。但是&a…

电子电路基础1(杂乱)

电路基础知识 注意&#xff1a;电压源与电流源的表现形式 注意&#xff1a;在同一根导线上电势相等 电阻电路的等效变换 电子元器件基础 电阻