数据库篇——锁

news2024/11/23 13:04:36

目录

引文A——活锁

引文B——死锁

1、表锁

1.1 关于 S 锁

1.2 关于 X 锁

1.3 关于意向锁

2、行锁

2.1 关于记录锁

2.2 关于间隙锁

2.3 关于临键锁

2.4 关于插入意向锁

3、页锁


我们在谈表锁、行锁以及页锁之前,先聊一聊 活锁🔒与 死锁🔒的问题  ( •̀ ω •́ )✧

引文A——活锁

举个栗子🤔:

  1. 现在有事务 A 获取到了该数据 data 的锁,这时,事务 B 又请求获取 data 锁,于是事务 B 进行等待...
  2. 此时,事务 C 也来获取 data 锁,事务 A 释放了 data 锁后首先批准了 事务 C 的请求,事务 B 仍然等待...以此类推.......
  3. 现在就有一个很严重的问题,事务 B 可能永远等待。这,就是经典的活锁问题

解决方法:

采用先来先服务的策略,当多个事务请求同一数据时,会按照请求获取锁的先后顺序进行事务排队,前一个事务一旦释放锁,就批准队列中第一个事务前来获取锁

  

引文B——死锁

举个栗子🤔:

  1. 现在有 事务A 获取到了数据 data1 的锁,而 事务B 获取到了数据 data2 的锁
  2. 这时,事务A 又来获取数据 data2 的锁,由于该数据已被事务B上锁,所以事务A进行等待事务B释放锁
  3. 好巧不巧,事务B 来获取数据 data1 的锁,而该数据是被 事务A 上锁的,所以事务B进行等待事务A释放锁
  4. 这样,就出现了 事务A 等待 事务B,而 事务B 又等待 事务A 的局面。这,就是经典的死锁问题

解决方法:

  • 使用 一次封锁法 或者使用 顺序封锁法 来进行死锁的预防
  • 使用 超时法 或者 事务等待图法 来进行死锁的诊断问题
  • 选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有锁,使其他事务得以继续运行下去来进行死锁的解除;当然,对撤销的事务所执行的数据修改操作必须加以恢复


1、表锁

一般情况下,不会使用 InnoDB 存储引擎提供的表级别的 S锁 和 X锁 。只会在一些特殊情况下,比方说 崩溃恢复 过程中用到。

需要注意的是:尽量不用手动添加表级锁,因为并不会提供什么额外的保护,只会降低并发能力

查看所有表中哪一个表使用了锁:

#这里是查看所有表中的使用锁的情况
show open tables; 

#这里是指定查看使用了锁的表
show open tables where in_use > 0;

释放锁:


unlock tables;

1.1 关于 S 锁

读锁(S锁) :也称为 共享锁 、英文用 S 表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。

添加表级读锁:


lock tables table(表名) read;

添加行级读锁:


#这里进行添加行级锁(共享锁)
SELECT * FROM mylock WHERE id = 1 LOCK IN SHARE MODE

1.2 关于 X 锁

写锁(X锁) :也称为 排他锁 、英文用 X 表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。

添加表级写锁:


lock tables table(表名) write;

添加行级写锁:


#这里进行添加行级锁(排他锁)
SELECT * FROM mylock WHERE id = 1 FOR UPDATE 

共享锁 与 排他锁 图解:

由于上面的操作的粒度太大,会导致表的效率降低,意向锁随之产生......

1.3 关于意向锁

定义:

InnoDB 支持 多粒度锁(multiple granularity locking) ,它允许 行级锁 与 表级锁 共存,而 “意向锁” 就是其中的一种 “表锁” 。

举个栗子🤔:

假如说现在有两个事务,分别是 T1 和 T2 ,其中 T2 试图在该表级别上应用共享或者排他锁;若没有意向锁的存在,那么 T2 就需要去检查各个页或行是否存在锁,这样的话,会导致效率很低;若加上意向锁,那么 T2 就不必分别检查各个页或行锁,而只需要检查表上的意向锁,这样效率就会提高很多

综上所述:

如果我们给某一行数据加上了某某锁,数据库内部引擎会自动给更大一级的空间,比如数据页或者数据表加上意向锁,告诉其他人这个数据页或者表已经有人加上过某某锁了

注意事项:

意向锁是由存储引擎自己维护的 ,用户无法手动操作意向锁,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行 所在数据表的对应意向锁 。

 意向锁之间关系图:

意向锁与非意向锁之间关系图:

意向锁的并发性:

其中,意向锁分为两种,分别为意向共享锁,以及意向排他锁

意向共享锁:

  事务有意向(数据库引擎自动添加)对表中的某些行加共享锁(S锁)


#事务要获取某些行的 S 锁,必须先获得表的 IS 锁。

SELECT column(字段) FROM table(表名) (其他条件)  LOCK IN SHARE MODE

意向排他锁:

  事务有意向(数据库引擎自动添加)对表中的某些行加排他锁(X锁)


#事务要获取某些行的 X 锁,必须先获得表的 IX 锁。

SELECT column(字段) FROM table(表名) (其他条件) FOR UPDATE;


2、行锁

行锁(Row Lock)也称为记录锁,顾名思义,就是将某一行锁住;需要注意的是,MySQL 服务器层并没有实现行锁机制,行级锁只存在于存储引擎层实现。 

优点:这样的锁粒度小,发生锁冲突的概率低,因而可以实现并发度高的情况

缺点:对锁的开销比较大(因为行相比于表,肯定行多),加锁会比较慢,容易出现死锁的情况

从这里我们可以发现, InnoDB 与 MyISAM 最大的不同点是:一是支持事务,二是采用了行级锁

2.1 关于记录锁

定义:

就是仅仅把一条记录锁上,官方的类型名称为: LOCK_REC_NOT_GAP 。

举个栗子🤔:

比如我们把 id 值为 8 的那条记录加一个记录锁(如图所示),仅仅是锁住了id值为 8 的记录,对周围的数据没有影响


BEGIN;  #进行开启事务

SELECT * FROM student WHERE  id = 8  FOR UPDATE;  #插入记录锁

记录锁是有S锁和X锁之分的,称之为 S型记录锁 和 X型记录锁 

  • 当一个事务获取了一条记录的S型记录锁后,其他事务也可以继续获取该记录的S型记录锁,但不可 以继续获取X型记录锁;
  • 当一个事务获取了一条记录的X型记录锁后,其他事务不可以继续获取该记录的S型记录锁,也不可以继续获取X型记录锁。

注意事项:

在进行 UPDATE 语句时,数据库内部引擎会自动加上锁;只有在 SELECT 语句时,才不会自动添加,只能手动添加,如: LOCK  IN  SHARE  MODE 或者  FOR UPDATE  来进行触发共享锁或者排他锁

2.2 关于间隙锁

定义:

所谓间隙锁(Gap  Locks),就是在数据之间的间隙处加上一把锁,防止别的事务在当前事务还在操作时,突然间又插入一条数据,从而解决幻读的问题;

举个栗子🤔:
 

假如现在有事务 A 和 事务 B两个事务。事务 A 先执行,该事务 A 在(3,8)这个范围之间添加了Gap 间隙锁;这时,事务 B 兴高采烈的跑过来,想在(3,8)这个区间内插入一条数据,好巧不巧,事务 A 已经添加了 Gap 锁,所以,事务 B 的 INSERT 操作是失败的,造成阻塞;直到事务 A COMMIT 提交过后,事务 B 才能继续执行 INSERT 语句;


BEGIN;  #进行开启事务

SELECT * FROM student WHERE  id < 8 AND  id > 3 FOR UPDATE;  #插入间隙锁

综上所述,Gap锁 仅仅是为了防止插入幻影记录(幻读)而提出的

2.3 关于临键锁

由来:

有时候我们既想锁住某条记录,又想阻止其他事务在当前事务下的间隙 INSERT 插入新的记录,这时,临键锁(Next-key  Locks)横空出世;其中,这是在 InnoDB 引擎、事务级别在可重复读的情况下使用的数据库锁(InnoDB 引擎默认使用的就是临键锁)

思维巧记:

临键锁 Next- key 其实就是一个 记录锁 和 一个 Gap 间隙锁 的合体,它既能保护该条记录,又能阻止别的事务将新的事务插入被保护记录之间的间隙中,避免幻读

举个栗子🤔:


BEGIN;  #进行开启事务

#这里 WHERE 条件 既规定了间隙,同时也指定了具体的记录
SELECT * FROM student WHERE  id <= 8 AND  id > 3 FOR UPDATE;  #插入间隙锁与记录锁


2.4 关于插入意向锁

举个栗子🤔:

我们说一个事务在插入一条记录时需要判断一下插入位置是不是被别的事务加了 gap锁 ( next-key锁也包含 gap锁 ),如果有的话,插入操作需要等待,直到拥有 gap锁 的那个事务提交。但是InnoDB规定事务在等待的时候也需要在内存中生成一个锁结构,表明有事务想在某个间隙中插入新记录,但是现在在等待,这个锁就叫做插入意向锁

注意事项:

  • 插入意向锁是一种 Gap锁 ,不是意向锁,在 INSERT 操作时产生。 插入意向锁是在插入一条记录行前,由 INSERT 操作产生的一种间隙锁 

  • 事实上 “插入意向锁” 并不会阻止别的事务继续获取该记录上任何类型的锁


3、页锁

定义:

就是在 页的粒度 上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录;当我们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一个页上的数据行

性能分析:

  • 页锁的开销介于表锁和行锁之间,会出现死锁
  • 锁定粒度介于表锁和行锁之间,并发度一般

 注意事项:

  • 每个层级的锁数量是有限制的,因为锁会占用内存空间, 锁空间的大小是有限的 。当某个层级的锁数量超过了这个层级的阈值时,就会进行 锁升级

  • 锁升级就是用更大粒度的锁替代多个更小粒度的锁,比如 InnoDB 中行锁升级为表锁,这样做的好处是占用的锁空间降低了,但同时数据的并发度也下降了

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

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

相关文章

RabbitMQ安装、端口修改、简单的角色介绍

前提 本文介绍RabbitMQ安装的环境是CentOS7版本的Linux云服务器。 官网&#xff1a;https://www.rabbitmq.com/ RabbitMQ的安装 由于RabbitMQ是使用Erlang语言开发的&#xff0c;所以我们在安装RabbitMQ之前需要在服务器中安装Erlang语言的环境。在Linux中执行下面命令&…

Day_43插入排序

目录 一. 关于插入排序 1. 排序的定义 2. 插入排序 二. 插入排序的实现过程 三. 代码实现过程 1. 插入排序核心代码 四. 代码展示 五. 数据测试 六. 总结 一. 关于插入排序 1. 排序的定义 排序&#xff0c;就是重新排列表中的元素&#xff0c;使表中的元素满足按关键字有序…

AIGC与AidLux互联应用——AidLux端AIGC测评(二)PC端云端Stable Diffusion模型推理应用(文生图,图生图)

在这里插入图片描述 Stable Diffusion模型搭建首先下载diffusers&#xff0c;然后安装&#xff0c;命令如下&#xff1a; git clone https://github.com/huggingface/diffusers.git pip install diffusers cd diffusers pip install . ubuntu和win系统下都可以 文生图&#x…

React Hooks 组件化开发(常用)

本文章视频地址&#xff1a;视频链接 一、React组件分类 二、Hook函数概览 Hook 是 React 16.8 的新增特性&#xff01;并且只能运用到函数组件中&#xff01; 1.useState 作用&#xff1a;在函数组件中使用状态&#xff0c;修改状态值可让函数组件更新&#xff0c;类似于类…

鸿蒙初识

学习官网&#xff1a;https://www.harmonyos.com/cn/develop 准备 注册&#xff0c;安装软件(node:12, DevEco Studio)&#xff1a; 在实际开发中node最好使用nvm进行版本管理。 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-00000010…

ChatGPT-Plugins-Searchable

ChatGPT Plus 用户应该都知道Plus已经开放了插件功能&#xff0c;但是在插件商店里存在一个较大的问题插件数量超过100款&#xff0c;却没有便捷的搜索功能。 而我们在查找一款插件时&#xff0c;需要从插件商店的第一页点击到最后一页一个个找&#xff0c;显然这非常的麻烦。 …

驱动开发--驱动模块

目录 1.驱动模块 hello.c Makefile 2.内核中的打印函数&#xff08;编写第一个驱动程序&#xff09; Source Insight 使用&#xff1a; 3.打印函数编写 分析 4、驱动的多文件编译 5、模块传递参数 6、安装好驱动之后如何传参&#xff1f; 7、字符设备驱动 8、字符设…

chatgpt赋能python:Python如何突破VIP限制

Python如何突破VIP限制 在这个数字内容时代&#xff0c;我们经常使用各种网站和应用程序来获取视频、音乐、软件等数字资源。但是&#xff0c;某些资源可能受到VIP限制&#xff0c;这意味着我们需要付费才能获得完整的访问权限。但是&#xff0c;如果你了解Python编程&#xf…

Agile | 聊聊敏捷开发

什么是敏捷开发 敏捷开发是一种迭代和增量的项目管理方法&#xff0c;优先考虑适应性、协作和快速交付&#xff0c;而不是遵循严格的计划[0]。它是在《敏捷软件开发宣言》和《12项原则》中表达的一组价值观和原则[1]。敏捷是基于这些价值观和原则的一组框架和实践的总称。敏捷…

【数据库】修改数据库密码及端口

一、修改MySQL配置文件 想要在没有密码的状态下修改MySQL的密码&#xff0c;必须跳过MySQL登录时的登录密码权限的验证&#xff0c;取消掉这个验证的方式如下&#xff1a; 1、找到MySQL的安装文件中的my.ini文件 一般人应该能找到的吧&#xff0c;配置MySQL的环境变量中也有安…

关于数据中心机房动环监控系统的应用与设计 安科瑞 许敏

摘 要&#xff1a; 机房动力和环境监控系统是对分布的精密机房及通信局&#xff08;站&#xff09;内的电源、空调、油机、蓄电池、高低压配电等多种设备和环境的各种参数、图像、声音等进行遥测、并对设备进行集中监控、集中维护和集中管理&#xff0c;是现代化机房管理手段和…

【Leetcode -138.复制带随机指针的链表 -2130.链表最大孪生和】

Leetcode Leetcode -138.复制带随机指针的链表Leetcode -2130.链表最大孪生和 Leetcode -138.复制带随机指针的链表 题目&#xff1a;给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构…

chatgpt赋能python:Python如何设置画笔颜色

Python如何设置画笔颜色 在Python中&#xff0c;有很多库可以用来画图&#xff0c;比如常用的Matplotlib、Seaborn和Plotly等等&#xff0c;但无论是哪种库&#xff0c;设置画笔颜色都是非常基础且重要的操作&#xff0c;因为它可以让我们更好地展示数据图表&#xff0c;突出重…

【TCP/IP】基于UDP的服务器端/客户端实现 II - 实践与实现

基于UDP的回声服务器端/客户端 结合之前基于TCP实现的回声服务器&#xff0c;我们尝试再用UDP来完成对回声服务器/客户端的设计。 echo_server: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa…

内蒙古自治区关于加快充换电基础设施建规划 安科瑞 许敏

摘要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升电动汽车充电基础设施服务保障能力的实施意见》&#xff08;发…

异常值检验(t分布查表)、方差分析

异常值检验 T-test 参考&#xff1a;1.ttest和ttest2 区别 2. ttest在 matlab 3.T test分布表 单侧 方差分析&#xff08;ANOVA&#xff09; Def: 方差分析&#xff08;analysis of variance, ANOVA&#xff09;是一种统计检验&#xff0c;用于检验两组或更多组样本的均值是…

PRL:上海交大张文涛团队实现量子材料相关突破

来源&#xff1a;上海交通大学 近期&#xff0c;上海交通大学物理与天文学院张文涛研究组利用自行研制的高能量和高时间分辨率角分辨光电子能谱系统对量子材料1T-TiSe₂电子结构进行了超快激光操控研究。利用超快光激发与电荷密度波相有关的相干声子&#xff0c;引起晶格内原子…

高压放大器在微波光子雷达中的应用有哪些

微波光子雷达是一种新型的雷达技术&#xff0c;它利用微波和光子相结合的方式进行探测和成像。在微波光子雷达系统中&#xff0c;高压放大器作为一个关键的组件&#xff0c;主要用于对微波信号进行放大&#xff0c;以增强雷达系统的探测能力和成像精度。本文将详细介绍高压放大…

20230606夏新(Amoi)的4K显示器D320B2000的亮点检测

20230606夏新&#xff08;Amoi&#xff09;的4K显示器D320B2000的亮点检测 2023/6/7 0:14 https://item.jd.com/63690000655.html 夏新&#xff08;Amoi&#xff09;电脑显示器高清家用办公电竞吃鸡游戏液晶监控直播大屏便携显示屏幕 32英寸【直面 4k/144hz双模式 全面屏】黑 …

Linux内核文件写入流程

文本代码基于Linux 5.15 。 当用户层调用write 去做写入&#xff0c; linux 内核里面是如何处理的&#xff1f; 本文以exfat 为例&#xff0c; 讨论这个流程 入口函数 write 系统调用的定义如下&#xff1a; fs/read_write.c ssize_t ksys_write(unsigned int fd, const ch…