mysql中的锁理解

在这里插入图片描述

1.共享锁,排他锁,也叫读锁和写锁

共享锁(S锁)(读锁):事务在读取记录的时候获取共享锁,允许其它事务同时获取共享锁。
排他锁(X锁)(写锁):事务在修改记录的时候获取排他锁,只允许一个事务获取排他锁,其它事务会阻塞等待。
在这里插入图片描述
读锁和写锁是互斥的:
一个事务占用了某条记录的读锁,另一个事务想要获取写锁(可以获取读),需要等待读锁先释放。
一个事务占用了某条记录的写锁,另一个事务想要获取读或者写锁,需要等待写锁先释放。

2.表锁、行锁、页锁

================================================================
表锁:对整张表进行加锁,加锁之后其它事务无法对表进行任何读写操作。
表锁又分为:
1)表级别的S锁、X锁:

LOCK TABLES t READ; # 存储引擎会对表t加表级别的共享锁。共享锁也叫读锁或S锁(Share的缩写)
LOCK TABLES t WRITE; # 存储引擎会对表t加表级别的排他锁。排他锁也叫独占锁、写锁或X锁(exclusive的缩写)

一般不会使用,锁定整张表效率低。
在这里插入图片描述
给表加了读锁之后,自己可以读,自己不能写,而且不能操作其它的表,他人可读,他人写的话得等待。
给表加了写锁之后,自己可以读,自己可以写,而且不能操作其它的表,他人读需要等待,他人写也得等待。

2)意向锁:
意向锁的存在是为了协调行锁和表锁的关系。
假如业务上真用到了表锁,那么表锁和行锁之间肯定会存在冲突,当InnoDB加表锁的时候,如何判断表里面是否有行锁?难道一条条记录遍历去找?效率太低。所以有了意向锁。

意向锁分为:意向共享锁(IS)、意向排他锁(IX)
意向共享锁(IS): 当需要对表中的记录加共享锁的时候,先在表上加个意向共享锁,表示此时表内有共享锁。

例如:

事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;

意向排他锁(IX): 当需要对表中的记录加排他锁的时候,先在表上加个意向排他锁,表示此时表内有排他锁。

例如:

事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;

这样一来,如果要加表锁,就不用去遍历了,直接根据意向锁进行判断。
如果要加表级别的S锁,如果表上没有IX,说明表中没有记录有排他锁,就可以直接上表级别的S锁。
如果要加表级别的X锁,如果表上没有IX和IS,说明表中的记录没有锁,就可以直接上表级别的X锁。

互斥性:
在这里插入图片描述

1.所有意向锁之间是相互兼容的。
2.只有表级别的共享锁和意向共享锁是兼容的,其它表级别的共享锁和排他锁和意向锁都是互斥的。
3.IX,IS是表级锁,不会和行级的X,S锁发生冲突。

例子:
事务A先获得了某一行的排他锁,并未提交:

BEGIN;
SELECT * FROM teacher WHERE id = 6 FOR UPDATE;

事务A获取了teacher表上的意向排他锁。事务A获取了id为6的数据行上的排他锁。
之后事务B想要获取teacher表上的共享锁。

BEGIN;
LOCK TABLES teacher READ;

事务B检测到事务A持有teacher表的意向排他锁。事务B对teacher表的加锁请求被阻塞(排斥)。
最后事务C也想获取teacher表中某一行的排他锁。

BEGIN;
SELECT * FROM teacher WHERE id = 5 FOR UPDATE;

事务C申请teacher表的意向排他锁。事务C检测到事务A持有teacher表的意向排他锁。
因为意向锁之间并不互斥,所以事务C获取到了teacher表的意向排他锁。因为id为5的数据行
上不存在任何排他锁,最终事务C成功获取到了该数据行上的排他锁。

3)元数据锁:
当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁。

读锁之间不互斥,因此你可以有多个线程同时对一张表增删查改。读写锁之间、写锁之间都是互斥的,用来保证变更表结构操作的安全性,解决了DML和DDL操作之间的一致性问题。
不需要显式使用,在访问一个表的时候会被自动加上。

4)自增锁:
用于自增列插入数据时使用。在插入数据的时候,会在表上加上auto-inc lock,然后为自增列分配递增的值在语句插入结束之后,再释放auto-inc lock。

自增锁是在语句插入结束之后才释放锁,效率比较低,所以后面弄了个互斥量(mutex)来进行自增减的累加,互斥量是在语句插入的时候,获取递增值之后,就可以释放锁,所以性能更好。

mysql有参数innodb_autoinc_lock_mode来控制使用自增锁还是互斥量,有3个值:
0:只使用自增锁
1:默认值,对于插入前已经知道行数的插入,用互斥量;插入前不知道具体插入行数的插入,用自增锁。这种最安全,statement格式的binlog也是安全的。
2: 只用互斥量

================================================================
行锁:仅对特定的行进行加锁,允许其它事务并发访问其它不同的行。
行锁又分为:
1)记录锁(record locks)
锁定当前的记录。对某条记录执行增删改的时候,会在这条记录上加记录锁。

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

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

2)间隙锁(Gap locks)
锁定的是一个间隙,防止其它事务插入数据到间隙中。
间隙锁之间不会冲突,也就是说不同的事务可以对同一个间隙同时加锁。因为间隙锁的目的是一致的,都是为了防止其它事务插入数据到间隙中。

3)临键锁(next-key locks)
临键锁 = 记录锁 + 间隙锁
除了锁定间隙,还锁定某条记录。

例如下面的语句:会产生临键锁,锁定id为8的这条记录,还锁定3~8的区间。锁定的范围是(3, 8].

begin;
select * from student where id <=8 and id > 3 for update;

4)插入意向锁
插入意向锁,它是一类间隙锁,但是它不是锁定间隙,而是等待间隙。

如果一个间隙上被加了间隙锁,这时候来了一个新的事务,想要往这个间隙上插入数据,那么这个事务会被间隙锁给阻塞,这时候新事务会生成一个插入意向锁,表示等待这个间隙锁的释放。

插入意向锁之间不会相互阻塞,因为他们的目的相同,都是等待这个间隙被释放。

3.页锁

================================================================
页锁:
页锁就是在 页的粒度 上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录。当我 们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一个页上的数据行。页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。

4.悲观锁,乐观锁

================================================================
乐观锁:
假设不会发生冲突,因此操作数据时不会加锁,只会在更新数据的时候做版本
校验,看数据有没有被别的事务修改,如果修改了,则拒绝当前事务的修改。
使用版本或者时间戳实现,一般是在数据库里面加一个版本或者时间戳字段。联想到CAS操作。适用于读多写少的场景。

悲观锁:
假设会发生冲突,操作数据之前都会对数据进行加锁,使其它的事务无法访问。
数据库提供的锁实现,例如表锁,行锁等。适用于写操作频繁的场景。

5.死锁

================================================================
死锁:
发生死锁怎么解决?
1.自动检测+锁等待时间+回滚
mysql会自动检测是否存在死锁,如果存在的话,会对一个事务进行回滚,并且释放该事务占有的锁;
有锁等待时间,如果一个事务获取锁的等待时间超过该阈值的时候,则回滚该事务,并且释放该事务占有的锁。
2.手动分析,kill发生死锁的事务的线程
show engine innodb status命令:分析死锁日志,找到发生死锁的事务以及线程id,然后kill;
通过查询information scheme,找到发生死锁的事务以及线程id,然后kill

避免死锁的手段:
1.避免长事务。长事务长时间占有锁,发生死锁的概率高。
2.降低事务隔离级别。例如使用读已提交隔离级别,比可重复读少了间隙锁,临建锁,可以减少死锁发生的概率。
3.合理建立索引。提高索引命中率,命中索引可以减少要处理的行,这样锁定的行也少,就可以减少死锁发生的概率。
4.开启死锁检测,适当调整锁等待时间。

死锁例子1:
在这里插入图片描述
在这里插入图片描述
死锁例子2:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】位图详解(一文彻底搞懂位图的使用方法与底层原理)

目录 1.位图的概念 2.位图的使用方法 定义与创建 设置和清除 位访问和检查 转换为其他格式 3.位图的使用场景 1.快速的查找某个数据是否在一个集合中 2.排序去重 3.求两个集合的交集和并集 4.位图的底层实现 私有成员定义与初始化 set和reset的实现 前面的博客我们…

补齐:相交链表:扣160

梦重新开始的地方 – 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。图示两个链表在节点 c1 开始相交&#xff1a; 示例&#xff1a; 何解&#xff1f; 暴力&…

Python:入门基础

目录 常量和表达式 变量 变量的语法 变量的类型 动态类型特性 注释的使用 输入和输出 通过控制台输出 通过控制台输入 运算符 算术运算符 关系运算符 逻辑运算符 赋值运算符 常量和表达式 print是Python中的一个内置函数&#xff0c;使用print函数可以将数据打印…

手动搭建koa+ts项目框架(node开发配置环境变量)

文章目录 一、安装所需依赖二、设置package.json三、定义ts &#xff08;可选&#xff09;四、配置环境变量文件五、引入变量文件总结如有启发&#xff0c;可点赞收藏哟~ 一、安装所需依赖 pnpm add dotenv二、设置package.json 先配置脚本设置对应环境变量NODE_ENV {"…

吞吐量最高飙升20倍!破解强化学习训练部署难题

**强化学习&#xff08;RL&#xff09;对大模型复杂推理能力提升有关键作用&#xff0c;然而&#xff0c;RL 复杂的计算流程以及现有系统局限性&#xff0c;也给训练和部署带来了挑战。近日&#xff0c;字节跳动豆包大模型团队与香港大学联合提出 HybridFlow&#xff08;开源项…

Unity 插件编译版本.net 4.0

项目中用到了Google.ProtocolBuffersLite.dll 这个动态链接库&#xff0c;在升级完Unity版本后出现了 ”Unity targets .NET 4.x and is marked as compatible with editor, Editor can only use assemblies targeting .NET 3.5 or lower“ 的问题。 解决方法&#xff1a; 1、…

Cpp二叉搜索树的讲解与实现(21)

文章目录 前言一、二叉搜索树的概念定义特点 二、二叉树的实现基本框架查找插入删除当只有0 ~ 1个孩子的时候当有2个孩子的时候 三、二叉树的应用K模型KV模型 四、二叉树的性能分析总结 前言 这是全新的一个篇章呢&#xff0c;二叉搜索树是我们接下来学习set、map的前提 迈过它…

Elasticsearch —— ES 环境搭建、概念、基本操作、文档操作、SpringBoot继承ES

文章中会用到的文件&#xff0c;如果官网下不了可以在这下 链接: https://pan.baidu.com/s/1SeRdqLo0E0CmaVJdoZs_nQ?pwdxr76 提取码: xr76 一、 ES 环境搭建 注&#xff1a;环境搭建过程中的命令窗口不能关闭&#xff0c;关闭了服务就会关闭&#xff08;除了修改设置后重启的…

第八届御网杯线下赛Pwn方向题解

由于最近比赛有点多&#xff0c;而且赶上招新&#xff0c;导致原本应该及时总结的比赛搁置了&#xff0c;总结来说还是得多练&#xff0c;因为时间很短像这种线下赛&#xff0c;一般只有几个小时&#xff0c;所以思路一定要清晰&#xff0c;我还是经验太少了&#xff0c;导致比…

Ethernet 系列(6)-- 基础学习::OSI Model

&#xff08;写在前面&#xff1a;最近在学习车载以太网的知识&#xff0c;顺便记录一下知识点。&#xff09; OSI&#xff08;Open System Interconnect &#xff09;模型是一种网络通信框架&#xff0c;由国际标准化组织&#xff08;‌ISO&#xff09;在1985年提出&#xff0…

Java 字符流详解

在 Java 的 I/O 体系中&#xff0c;字符流&#xff08;Reader 和 Writer&#xff09;是专门用于处理文本数据的输入输出流。与字节流不同&#xff0c;字符流以字符为单位进行读取和写入&#xff0c;能够更好地处理文本信息&#xff0c;尤其是包含多字节字符&#xff08;如中文&…

Linux 多线程编程

韦东山的例程所谓线程&#xff0c;就是操作系统所能调度的最小单位。普通的进程&#xff0c;只有一个线程在执行对应的逻辑。我们可以通过多线程编程&#xff0c;使一个进程可以去执行多个不同的任务。相比多进程编程而言&#xff0c;线程享有共享资源&#xff0c;即在进程中出…

后端:Spring-1

文章目录 1. 了解 spring(Spring Framework)2. 基于maven搭建Spring框架2.1 纯xml配置方式来实现Spring2.2 注解方式来实现Spring3. Java Config类来实现Spring 2.4 总结 1. 了解 spring(Spring Framework) 传统方式构建spring(指的是Spring Framework)项目&#xff0c;导入依…

【C++动态规划 01背包】2787. 将一个数字表示成幂的和的方案数

本文涉及知识点 C动态规划 C背包问题 LeetCode2787. 将一个数字表示成幂的和的方案数 给你两个 正 整数 n 和 x 。 请你返回将 n 表示成一些 互不相同 正整数的 x 次幂之和的方案数。换句话说&#xff0c;你需要返回互不相同整数 [n1, n2, …, nk] 的集合数目&#xff0c;满…

Python爬虫的京东大冒险:如何高效获取商品详情的秘籍

在这个由代码编织的电商世界里&#xff0c;京东商品详情就像是被锁在高塔中的公主&#xff0c;等待着勇敢的Python爬虫骑士去解救。今天&#xff0c;我们要讲述的是如何成为一名Python爬虫骑士&#xff0c;携带你的代码长矛&#xff0c;穿梭在API的数据森林中&#xff0c;高效获…

SpringBoot【实用篇】- 测试

文章目录 目标&#xff1a;1.加载测试专用属性3.Web环境模拟测试2.加载测试专用配置4.数据层测试回滚5.测试用例数据设定 目标&#xff1a; 加载测试专用属性加载测试专用配置Web环境模拟测试数据层测试回滚测试用例数据设定 1.加载测试专用属性 我们在前面讲配置高级的时候…

vfx特效有多烧钱?云渲染农场减少vfx特效成本

特效制作一直是电影制作中的烧钱大户&#xff0c;尤其是视觉特效&#xff08;VFX&#xff09;的高昂成本让许多项目望而却步。但随着云渲染农场技术的发展&#xff0c;VFX特效的成本得到了有效控制&#xff0c;为电影工业带来了革命性的变化。 在电影工业中&#xff0c;VFX特效…

任何python安装gdal出现的问题

Releases cgohlke/geospatial-wheels GitHubGeospatial library wheels for Python on Windows. Contribute to cgohlke/geospatial-wheels development by creating an account on GitHub.https://github.com/cgohlke/geospatial-wheels/releases 各种乱七八糟的gdal库问题…

tensorflow案例4--人脸识别(损失函数选取,调用VGG16模型以及改进写法)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 这个模型结构算上之前的pytorch版本的&#xff0c;算是花了不少时间&#xff0c;但是效果一直没有达到理想情况&#xff0c;主要是验证集和训练集准确率…

SPA和SSR

单页面应用程序(SPA) 单页面应用(SPA)全称是:Single-page application, SPA应用是在客户端呈现的(术语称:CRS)。 SPA应用默认只返回一个空HTML页面&#xff0c;如:body只有<div id"app"></div>而整个应用程序的内容都是通过JavaScript动态加载&#xf…