MySQL | 行锁——记录锁、间隙锁 、临键锁、插入意向锁
1、InnoDB中的行锁
行锁(Row Lock) 也称为记录锁,顾名思义,就是锁住某一行(某条记录row)。需要注意的是,MySQL服务器层并没有实现行锁机制,行级锁只在存储引擎层实现。
优点:锁定力度小,发生锁冲突概率低,可以实现的并发度高。
缺点:对于锁的开销比较大,加锁会比较慢,容易出现死锁情况。
InnoDB与MyISAM的最大不同有亮点:一是支持事务;二是采用了行级锁。
1、记录锁(Record Locks)
记录锁页就是仅仅把一条记录锁上,官方的类型名称为:Lock_REC_NOT_GAP。比如把id值为1的那条记录加一个记录锁。仅仅是锁住了id值为1的记录,对其他行的数据没有影响。
记录锁是有S锁和X锁之分的,称之为S型记录锁和X型记录锁
- 当一个事务获取了一条记录的S型记录锁后,其他事务也可以继续获取该记录的S型记录锁,但不可以继续获取X型记录锁;
- 当一个事务获取了一条记录的X型记录锁后,其他事务既不可以继续获取该记录的S型记录锁,也不可以继续获取X型记录锁。
举例:记录锁的使用场景模拟
场景1:事务1开启S锁,事务2开始S锁并且尝试获取X型记录锁
事务1:开启S锁
mysql> begin;
Query OK, 0 rows affected (0.01 sec)mysql> select * from user where id = 1 lock in share mode;
+----+---------+
| id | name |
+----+---------+
| 1 | 张三3 |
+----+---------+
1 row in set (0.00 sec)
事务2:开启S锁,尝试获取X锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 1 lock in share mode;
+----+---------+
| id | name |
+----+---------+
| 1 | 张三3 |
+----+---------+
1 row in set (0.00 sec)mysql> update user set name = "张三4" where id = 1;
此时事务2获取S锁成功,获取X锁失败进行阻塞状态。
场景2:事务1开启X锁,事务2尝试获取X锁和S锁
事务1:开启X锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 1 for update;
+----+---------+
| id | name |
+----+---------+
| 1 | 张三3 |
+----+---------+
1 row in set (0.00 sec)
事务2:尝试获取X锁和S锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 1 ;
+----+---------+
| id | name |
+----+---------+
| 1 | 张三3 |
+----+---------+
1 row in set (0.00 sec)mysql> select * from user where id = 1 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> update user set name = "张三10" where id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>
事务2获取X锁和S锁失败,进入阻塞
场景3:事务1对id值为1的进行加S锁,事务2对id值的5的加X锁。
事务1:开启S锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 1 lock in share mode;
+----+---------+
| id | name |
+----+---------+
| 1 | 张三3 |
+----+---------+
1 row in set (0.00 sec)
事务2:获取X锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update user set name = "王五2" where id = 5;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
事务2获取X锁成功。如果对同一行记录进行加锁则事务2获取X锁失败,对不同的行进行加锁则互不影响。
2、间隙锁 (Gap Locks)
MySQL 在 REPEATABLE READ 隔离级别下是可以解决幻读问题的,解决方案有两种,可以使用 MVCC 方案解决,也可以采用加锁 方案解决。但是在使用加锁方案解决时有个大问题,就是事务在第一次执行读取操作时,那些幻影记录尚不存在,我们无法给这些幻影记录加上记录锁。InnoDB提出了一种称之为 **Gap Locks **的锁,官方的类型名称为: LOCK_GAP ,我们可以简称为 gap锁。比如,把id值为8的那条记录加一个gap锁的示意图如下。
id | 1 | 3 | 5 | 8 |
---|---|---|---|---|
name | 李四 | 张三 | 王五 | 赵六 |
图中id值为8的记录加了gap锁,意味着**不允许别的事务在id值为8的记录前边的间隙插入新记录 **,其实就是id列的值(5,8)这个区间的新记录是不允许立即插入的。比如,有另外一个事务再想插入一条id值为6的新记录,它定位到该条新记录的下一条记录的id值为8,而这条记录上又有一个gap锁,所以就会阻塞插入操作,直到拥有这个gap锁的事务提交了之后,id列的值在区间(5,8)中的新记录才可以被插入。
gap锁的提出仅仅是为了防止插入幻影记录而提出的。虽然有 共享gap锁 和独占gap锁 这样的说法,但是它们起到的作用是相同的。而且如果对一条记录加了gap锁(不论是共享gap锁还是独占gap锁),并不会限制其他事务对这条记录加记录锁或者继续加gap锁。
举例:间隙锁的使用场景模拟
事务1:加S锁
mysql> select * from user;
+----+------------+
| id | name |
+----+------------+
| 1 | 张三3 |
| 3 | 张胜男2 |
| 5 | 王五2 |
| 8 | 赵六 |
| 10 | 张三10 |
+----+------------+
5 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 6 lock in share mode;
Empty set (0.00 sec)mysql>
事务2:加X锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 6 for update;
Empty set (0.00 sec)mysql>
事务3:新增数据
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into user (`id`,`name`) values (7,"李四33");
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql> insert into user (`id`,`name`) values (2,"李四33");
Query OK, 1 row affected (0.00 sec)
间隙锁加的是6,所以间隙范围是5-8,新增id为7则失败,新增id为2则成功。
3、临键锁 (Next-Key Locks)
有时候我们既想 锁住某条记录 ,又想 阻止其他事务在该记录前边的 间隙插入新记录,所以innoDB就提出了一种称之为Next-Key Locks的锁,官方的类型名称为: LOCK_ORDINARY,我们也可以简称为next-key锁。Next-KeyLocks是在存储引擎 innodb 、事务级别在 **可重复读 **的情况下使用的数据库锁,innodb默认的锁就是Next-Keylocks。
next-key锁 的本质就是一个 记录锁 和一个 gap锁 的合体,它既能保护该条记录,又能阻止别的事务将新记录插
入被保护记录前边的 间隙。
举例:临键锁的使用场景模拟
事务1:加X锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id <=8 and id >5 for update;
+----+--------+
| id | name |
+----+--------+
| 8 | 赵六 |
+----+--------+
1 row in set (0.00 sec)
事务2:尝试获取X锁和S锁,并且尝试插入数据
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 8 lock in share mode;
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql> select * from user where id = 8 for update;
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql> insert into user (id,name) values (7,"李四2323");
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
事务2都需要进行等待,满足间隙锁和记录锁要求
4、插入意向锁(Insert Intention Locks)
我们说一个事务在 插入 一条记录时需要判断一下插入位置是不是被别的事务加了 gap锁 (next-key锁 也包含gap锁),如果有的话,插入操作需要等待,直到拥有 gap锁 的那个事务提交。但是InnoDB规定事务在等待的时候也需要在内存中生成一个锁结构,表明有事务想在某个 间隙 中 插入新记录,但是现在在等待。InnoDB就把这种类型的锁命名为Insert Intention Locks,官方的类型名称为:LOCK_INSERT_INTENTION,我们称为插入意向锁 。插入意向锁是一种 Gap锁,不是意向锁,在insert操作时产生。
插入意向锁是在插入一条记录行前,由INSERT 操作产生的一种间隙锁。该锁用以表示插入意向,当多个事务在同一区间(gap)插入位置不同的多条数据时,事务之间不需要互相等待。假设存在两条值分别为4和7的记录,两个不同的事务分别试图插入值为5和6的两条记录,每个事务在获取插入行上独占的(排他)锁前,都会获取(4,7)之间的间隙锁,但是因为数据行之间并不冲突,所以两个事务之间并不会产生冲突(阻塞等待)。总结来说,插入意向锁的特性可以分成两部分:
- 插入意向锁是一种特殊的间隙锁– 间隙锁可以锁定开区间内的部分记录,
- 插入意向锁之间互不排斥,所以即使多个事务在同一区间插入多条记录,只要记录本身(主键、唯一索引)不冲突,那么事务之间就不会出现冲突等待。
注意,虽然插入意向锁中含有意向锁三个字,但是它并不属于意向锁而属于间隙锁,因为意向锁是表锁而插入意向锁是行锁 。
从图中可以看到,由于T1持有gap锁,所以T2和T3需要生成一个插入意向锁的锁结构并且处于等待状态。当T1提交后会把它获取到的锁都释放掉,这样T2和T3就能获取到对应的插入意向锁了(本质上就是把插入意向锁对应锁结构的is_waiting属性改为false)T2和T3之间也并不会相互阻塞,它们可以同时获取到id值为8的插入意向锁,然后执行插入操作。事实上插入意向锁并不会阻止别的事务继续获取该记录上任何类型的锁。
举例:插入意向锁的使用场景模拟
场景:事务1开启间隙锁,事务2和事务3分别插入数据,在事务1不提交之前,事务2和事务3都是进入阻塞状态,直到事务1提交,事务2和事务3同时成功
事务1:开启间隙锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where id = 6 for update;
Empty set (0.00 sec)
事务2:插入数据
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into user (id,name) values (7,"李四2323");
Query OK, 1 row affected (34.91 sec)
事务3:插入数据
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user (id,name) values (6,"李四2323");
Query OK, 1 row affected (6.35 sec)
事务1未提交,事务2和事务3进入阻塞状态,事务1提交,事务2和事务3则新增成功
MySQL | 表锁——排他锁、共享锁、意向锁、元数据锁
相关文章:
MySQL | 行锁——记录锁、间隙锁 、临键锁、插入意向锁
1、InnoDB中的行锁 行锁(Row Lock) 也称为记录锁,顾名思义,就是锁住某一行(某条记录row)。需要注意的是,MySQL服务器层并没有实现行锁机制,行级锁只在存储引擎层实现。 优点&#x…...
【网络编程】TCP通信基础模型实现
tcpSer.c #include <myhead.h> #define SER_IP "192.168.119.143" // 设置IP地址 #define SER_PORT 6666 // 设置端口号 int main(int argc, const char *argv[]) {// 1.创建socketint serfd socket(AF_INET, SOCK_STREAM, 0);// 参数1表示ipv4// 参数2表…...
css rem之2024
话题开始前 我们都知道1rem是等于html fontSize标签的字体大小的,我们主要用来做移动端网页设计稿等比例在手机上面的显示。 看到的问题 这个html fontsize的大小是通过js动态计算的,而这个js的运行时晚于html渲染的,所以会导致一个问题&am…...
python自动化笔记:pytest框架
目录 一、pytest介绍二、测试用例命名规则2.1、pytest命名规则2.2、python命名规范 三、pytest运行方式3.1、主函数方式3.2、命令行方式3.3、通过pytest.ini的配置文件运行(常用) 四、跳过测试用例4.1 无条件跳过4.2 有条件跳过 五、用例的前后置&#x…...
wpf 路径动画 举例
先,我们需要在XAML中定义一个Path,这个Path将定义动画的路线。然后,我们将使用DoubleAnimationUsingPath来沿着这个路径移动一个元素(比如一个矩形)。 <Window x:Class"WpfApp.MainWindow" xmlns"…...
【C++】classes and object 2.8 取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; class Date { public:Date* operator&(){return this;}const Date* operator&()const{return this;} privat…...
milvus helm k8s开启监控
https://milvus.io/docs/monitor.md 文章写的很清晰 ,我这边做一下个人补充,初版可能只是配置,具体的grafana 监控报表后期补一下。 架构如下: values.yaml 配置 enabled: true 改为true metrics:enabled: trueserviceMonitor:…...
牛奶饮用学习笔记
1. 常见牛奶类型 1.1 蒙牛-每日鲜语-0脂肪鲜牛奶 项目每100mL NRV%能量146kJ 能量计算 250 mL 146 kJ / 100 mL 365 kJ 250\text{mL}\times146\text{kJ}/100\text{mL} 365\text{kJ} 250mL146kJ/100mL365kJ 1.2 伊利-舒化-高钙型无乳糖牛奶 项目每100mL NRV%能量269kJ …...
php防止页面重复刷新或者重复提交
2.核心代码 显示的逻辑: //获取防止刷新的唯一标识符,start $intFlag substr(md5(time()),6); $strFlag BAOXIAOSS_.$my_user_id.$intFlag; $smarty->assign(check_is_agin_post, $strFlag); //获取防止刷新的唯一标识符,end注意:前端页面提交加入…...
Springboot3 配置sql打印到控制台
一、pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><version>3.1.2</version></dependency> 二、application.yml com.lingyang.system # log4j2配…...
深入理解 GO 语言并发
1. 使用并发 在深入了解 Go 如何处理并发之前,先查看并发的概念。在计算机发展的早期阶段,计算机系统只有一个处理器负责执行所有指令。由于这种体系结构,计算机程序被编写成以串行的方式运行,在这种方式下,程序按照预定义的顺序逐个指令地执行。 随着计算机程序变得越来越…...
leetcode39组合总和
题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选…...
【JPCS独立出版,EI稳定检索】2024年工业机器人与先进制造技术国际学术会议(IRAMT 2024,9月27-29)
2024年工业机器人与先进制造技术国际学术会议(IRAMT 2024)将于2024年9月27-29日在中国成都举办。 此次会议将围绕工业机器人、机电技术、机械及制造等领域的最新研究成果展开讨论,并广泛邀请了国内外领域内的著名专家与学者。会议旨在搭建一个…...
Fal.ai Flux 1-Pro/Viva.ai/哩布哩布AI:AI绘图部分免费工具+原图提示词Prompt
目录 #1 找软件 #2 懂提示词 #3 更难的一步,会英文 我个人认为,想要玩文生图,你要会3个步骤: #1 找软件 主流文生图软件:Midjourney、Stable Diffusion、Dall-E 3 巧了,我用的都是小众、免费的画笔工…...
C++学习笔记----2、使用C++进行优雅编程(十)---- 格式化
许多人因为编程风格的问题被搞得焦头烂额,就因为对于在if中使用几个空格争论不休,导致友谊的小船说翻就翻。如果公司有相应的编程规范,只能说你比较幸运。因为有可能你不喜欢这些规范,但做为一个正常人来讲,至少有规范…...
双指针| Java | (hot100) 力扣283, 11, 15, 42做题总结
leetcode 11 盛最多水的容器 双层for循环暴力 超出时间限制 class Solution {public int maxArea(int[] height) {int h0;int v0;for(int i0; i<height.length; i) {for(int ji1; j<height.length; j) {h Math.min(height[i],height[j]);v Math.max(v, h*(j-i));}}…...
matlab求解方程
【MATLAB】求解含有三角函数的方程_matlab求解三角函数方程-CSDN博客 Matlab求解方程或函数的根,root,fzero,solve,fsolve的区别_matlab root-CSDN博客 非线性方程(组):MATLAB内置函数 solve, vpasolve, fsolve, fzero, roots [MATLAB] - GentleMin - …...
MySQL基础--视图,存储过程
介绍 视图是一种虚拟存在的表,视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图只保存了查询的 SQL 逻辑,不保存查询结果,所以我…...
学习记录第二十六天
进程运行 1,子进程和父进程做相同的事----创建子进程 执行任务 2,子进程做与父进程不同的事 ----fork exec exec族 l VS v :主要是第二个参数的传参方式不同 p :表示寻找可执行文件 是通过PATA环境变量 e : 表示可以给…...
Polars简明基础教程十一:可视化(一)
到本次讲座结束时,你将能够: 使用Polars的内部plot方法从Polars创建图表使用外部绘图库从Polars创建图表了解这些库如何支持Polars 通常,需要可视化库的最新版本来实现最大程度的兼容性 import polars as plimport hvplot as hv import ma…...
实战项目:贪吃蛇游戏的实现(上)
前言 Hello, 今天我们来一起完成一个实战项目:贪吃蛇。 相信大家都不会对这个游戏感到陌生,贪吃蛇游戏是久负盛名的游戏,他和俄罗斯方块,扫雷游戏等游戏位列世界经典游戏之列。这次我们旨在通过实战项目贪吃蛇的实现,…...
SHT30温湿度传感器全解析——概况,性能,MCU连接,样例代码
常见温湿度传感器测量范围:(价格仅供参考,具体性能要看折线图) 型号DHT11DHT20AHT10AHT20AHT30SHT20价格¥ 2.49¥3.04¥ 1.9¥1.4¥ 1.3¥5.5温度测量范围20—90%RH0—100%RH0—100%RH0—…...
SQL server 同环比计算模板
1、计算 月 年 季度的环比和同比 计算公式如下: 环比增长率 (本期数 - 上期数) / |上期数| 100% 同比增长率 (本期数 - 同期数) / |同期数| * 100% --- dbo.ads_erp_finance_gross_profit_actual_invoice_yoy_m…...
python发送外部请求
在Python中,服务器发送外部请求是一个常见的操作,尤其是在需要集成不同服务或API时。有多种库可以帮助你完成这项任务,但最流行和广泛使用的库之一是requests。以下是如何使用requests库在Python服务器中发送外部请求的基本步骤: …...
c++并发编程面试题
1. C中lock_guard和unique_lock的区别? 在C中,lock_guard和unique_lock都是用于管理互斥锁的类,它们提供了一种 RAII(Resource Acquisition Is Initialization)机制来确保锁在作用域结束时自动释放。尽管它们的目的相…...
K8S上安装LongHorn(分布式块存储) --use
要在 Kubernetes上安装 LongHorn,您可以按照以下步骤进行操作: 准备工作 参考 官网教程将LongHorn只部署在k8s-worker5节点上。https://github.com/longhorn/longhorn 安装要求 Each node in the Kubernetes cluster where Longhorn is installed must f…...
2024年前端技术发展趋势分析
2024年的前端技术发展趋势继续受到快速变化的技术环境和不断增长的用户期望的影响。以下是2024年前端技术发展的几个关键趋势: 1. Web 组件和自定义元素 Web 组件技术(包括 Shadow DOM、HTML Templates 和 Custom Elements)正在成为构建可重…...
spring boot 笔记大杂烩
一,springboot项目创建 springboot创建时idea会打开start.spring.io失败报错 可以手动打开这个页面,然后选择maven项目,然后修改group和name名然后添加依赖web,然后生成项目包,解压缩后用idea打开就能用了 运行后报错…...
如何在香港云服务器上优化网站性能?
在香港云服务器上优化网站性能可以通过以下几种方式进行,确保用户从全球各地访问时获得快速、稳定的体验: 1. 使用内容分发网络 (CDN) 优势:CDN可以将静态内容(如图像、视频、CSS、JavaScript文件)缓存到全球多个节点…...
STM32低功耗与备用备份区域
STM的备份备用区域其实就是两个区块:BKP和RTC。低功耗则其实是STM32四种模式中的三种耗能很低的模式。 目录 一:备用区域 1.BKP 2.RTC 二:低功耗模式 1.睡眠模式: 2.停机模式: 3.待机模式: 一&…...
建设商务网站的步骤/最近时事新闻热点事件
背景: 我的jira数据库中已有数据,想修改数据集,不能通过简单的修改字符集完成,需要先将原数据导出,经过适当调整后重新导入才可完成。 下面的步骤可以进行问题的解决(假设原字符集是latin1,想修…...
重庆怎么做网站?/b站推广入口
Oracle 常用初始化命令--创建一个表空间CREATE TABLESPACE MYSPACE DATAFILE D:/MYSPACE.DBF SIZE 10M AUTOEXTEND ON--指定某个用户的默认的表空间是MYSPACEALTER USER SYSTEM IDENTIFIED BY NIIT DEFAULT TABLESPACE MYSPACE QUOTA UNLIMITED ON MYSPACECOMMIT--删除表空间DR…...
个人信息网站建设的心得体会/常见的网络营销工具有哪些
飞机大战 java 源代码 (19页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!14.9 积分package com;import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image;…...
湖南品牌网站建站可定制/本网站三天换一次域名
2019独角兽企业重金招聘Python工程师标准>>> hdfs优点: -高容错性:多副本;副本丢失后可以自动恢复-适合批处理:移动计算而非数据;数据位置暴露给计算框架-适合大数据库处理:TB,PB量级数据处理&a…...
网站建设我要自学网/宣传推广方案
自然框架里的元数据 元数据的职责: 自然框架里的元数据有三个职责:描述数据库(字段、表、视图等),描述项目(功能节点、操作按钮等),项目和数据库的关系(一个列表页面里…...
网页设计入门 电子书下载/江西seo推广软件
1.插件介绍 redis simple插件。 连接redis,进行查看、修改、删除数据。 2.安装方式 第一种方式,是在IDEA上搜索插件进行安装,会适配当前IDEA的版本。 第二种安装方式是使用离线插件进行安装。 插件下载地址:https://plugins.…...