当前位置: 首页 > news >正文

MySQL-锁

MySQL的锁机制

在这里插入图片描述

1.共享锁(Shared Lock)和排他锁(Exclusive Lock)

事务不能同时具有行共享锁和排他锁,如果事务想要获取排他锁,前提是行没有共享锁和排他锁。而共享锁,只要行没有排他锁都能获取到。

手动开启共享锁/排他锁:

-- 对需要查询的行添加共享锁
select .... from .... lock in share mode;
-- 对读取记录加排他锁
select .... from .... for update;

注意:当一个事务尝试获取一个已经被其他事务持有的排他锁时,它会进入等待状态,直到该锁被释放为止。在MySQL 8.0版本中,新增了NOWAIT和SKIP LOCKED两种语法,可以用来控制事务在获取不到锁时的行为。

delete操作过程:

  1. 事务开始,获取待删除数据的排他锁。
  2. 获取成功,执行删除操作。
  3. 事务提交
  4. 释放锁。

update操作过程:分为两种情况,有更改主键值和未修改主键值。

未修改主键值:

  1. 更新前后存储空间未发生变化:获取排他锁,在原记录进行修改。
  2. 更新前后存储空间发生变化:获取排他锁,将该记录删除,最后在插入一条新的记录。

修改主键值:在原记录进行一次delete操作,再来一次insert操作。

insert操作过程:一般情况下,insert操作并不加锁,通过一种隐式锁保护新插入的记录不被未提交的事务所看到。

注意:共享锁->排他锁(阻塞)+共享锁(阻塞)

2.表锁

2.1X锁和S锁

表锁:锁定整张表,不依赖于存储引擎,表锁的开销较小,但是锁粒度大,并发执行效率低。

特殊场景:在修改表结构的过程中像alter table 、drop table这样的语句,就会有表锁的存在,同时也会阻塞其他对表的操作语句(update、select…)。

表级别的X锁和S锁:

-- 添加S锁(InnoDB引擎会对表table添加S锁)
LOCK TABLES table READ;
-- 添加X锁(InnoDB引擎会对表table添加X锁)
LOCK TABLES table WRITE;
-- 解锁
UNLOCK TABLES;

2.2意向锁(intention lock)

InnoDB支持多粒度锁,允许行级锁和表级锁共存。

  1. 为了协调行锁和表的关系,支持多粒度锁共存。

存在的问题:如果数据量非常大,表如果要知道哪一行存在锁,就非常的麻烦,因此就有了意向锁。

如果我们给某一行的数据添加了锁,数据库会自动给更大的一级空间,比如数据页或表添加上意向锁,表示该数据页或数据表已经存在锁了。

-- 事务要获取某个行的S锁,必须先获得IS锁。
SELECT ... FROM table ... LOCK IN SHARE MODE;
-- 添加排他锁,会自动获取IS锁。
SELECT... FROM table ... for UPDATE;

意向锁和意向锁的兼容性:

意向共享锁意向排他锁
意向共享锁兼容兼容
意向排他锁兼容兼容

意向锁和表锁的兼容性:

意向共享锁意向排他锁
共享锁兼容不兼容
排他锁不兼容不兼容

2.3自增锁

表中字段存在AUTO_INCREMENT属性。当新增数据自动生成主键时,就会使用该锁来生成,保证生成的主键是自增且唯一的。

AUTOINC 锁具有如下特点:

  1. AUTO_INC 锁互不兼容,也就是说同一张表同时只允许有一个自增锁;
  2. 自增值一旦分配了就会 +1,如果事务回滚,自增值也不会减回去,所以自增值可能会出现中断的情况。

2.4元数据锁

主要为了解决表结构的修改和表数据修改冲突问题。

当对一个表增删改查操作的时候,加MDL读锁;当要对表结构变更操作的时候,加MDL写锁。

3.乐观锁和悲观锁

3.1乐观锁

实现乐观锁可以采用CAS(Compare And Swap)的方式,乐观的认为产生锁冲突的概率较小。适用于锁冲突概率比较小的场景。

在这里插入图片描述

ABA问题:假设最开始的数据是A,在线程1执行的过程中,有其他线程将数据修改成了B,又再次被修改为A,就会导致线程1错误的认为该数据没有被修改过,因此可以通过对数据添加一个版本号,对于每次修改,都会产生一个新的修改数据版本,通过比较数据版本判断数据是否被更改。

时间戳机制:通过比较时间戳判断数据是否被修改。

3.2悲观锁

悲观锁:依靠数据库提供的锁机制来实现。

SELECT … FOR UPDATE是MySQL中的悲观锁,执行过程会将所有扫描的行都锁上,因此在MySQL中用悲观锁必须使用索引,而不是全表扫描,否则会将整张表锁住。

4.行锁

4.1记录锁

SELECT ... FROM ... WHERE id = 1 FOR UPDATE;

记录锁:记录锁(Record Lock)是一种锁定索引记录的锁定方式。当一个事务需要访问某个索引记录时,它可以在该记录上加一个记录锁,以防止其他事务修改或删除该记录。记录锁是针对单个记录的,它只锁定该记录本身,不会影响其他记录。

4.2间隙锁

间隙锁在REPEATABLE READ隔离级别下是可以解决幻读问题的。给不存在的索引添加锁,那么添加的就是间隙锁。

例如有id ={1,3,5,8,10,15},锁定13,那么在区间(10,15)之间都不能插入新的数据。

SELECT ... FROM ... WHERE id = 13 FOR UPDATE;

注意:间隙锁的唯一目的就是阻止其他事务在间隙上插入记录,一个事务在一个间隙上加锁并不会阻止其他事务在相同间隙上加锁,无论是共享锁还是排它锁,他们互不冲突,执行相同的功能。

4.3临键锁

临键锁:临键锁(Next-Key Lock)是结合记录锁和间隙锁的一种锁定方式。它不仅锁定索引上的记录,还锁定该记录前面的间隙。

例如有:id={1,3,5,8,10,15},记录15被锁定了,且(10,+∞)不能添加记录。

SELECT ... FROM ... WHERE id<=15 AND id>10 for update;

4.4插入意向锁

插入意向锁(Insert Intention Lock)是MySQL中的一种间隙锁形式的意向锁,用于在INSERT操作之前设置。

在真正执行INSERT操作之前,每个事务会在要插入的行的前一条记录上加一个插入意向锁。这样,其他事务在尝试插入相同间隙时,会检查该间隙上是否已经存在插入意向锁。如果存在插入意向锁,那么其他事务就可以知道已经有其他事务打算在这个间隙中插入数据,就会进行等待而不是冲突。

由于插入意向锁之间不会相互冲突,多个事务可以同时持有相同间隙上的插入意向锁。这就避免了事务之间的互相冲突,提高了并发插入的性能。

需要注意的是,插入意向锁之间并不会相互冲突,多个事务可以同时持有相同间隙上的插入意向锁。

5.全局锁

锁整个数据库实例。

全局锁命令:

FLUSH TABLES WITH READ LOCK;

有相同间隙上的插入意向锁。这就避免了事务之间的互相冲突,提高了并发插入的性能。

需要注意的是,插入意向锁之间并不会相互冲突,多个事务可以同时持有相同间隙上的插入意向锁。

5.全局锁

锁整个数据库实例。

全局锁命令:

FLUSH TABLES WITH READ LOCK;
http://www.lryc.cn/news/186969.html

相关文章:

  • ES6中变量解构赋值
  • Dijkstra 邻接表表示算法 | 贪心算法实现--附C++/JAVA实现源码
  • 从城市吉祥物进化到虚拟人IP需要哪些步骤?
  • 认识SQLServer
  • Python开发IDE的比较:PyCharm vs. VS Code vs. Jupyter
  • 1206. 设计跳表
  • 【API要返回一棵树的结构】数据库表结构是平铺的数据,但是api要实现树状结构展示。api实现一棵树的结构,如何实现呢,递归?如何递归呢
  • 视频批量剪辑工具,自定义视频速率,批量剪辑工具助力创意无限”
  • starrocks启动和停止和重启脚本
  • 升级Xcode 15后,出现大量Duplicate symbols问题
  • Godot2D角色导航教程(角色随鼠标移动)
  • 论文阅读--Cell-free massive MIMO versus small cells
  • 【深度学习】UniControl 一个统一的扩散模型用于可控的野外视觉生成
  • 使用ChatGPT和MindShow一分钟生成PPT模板
  • C#对字典容器Dictionary<TKey, TValue>内容进行XML序列化或反序列化报错解决方法
  • 【Linux】Linux 之用户管理
  • NLP:Attention和self-attention的区别
  • Gap Year Plan
  • 厌烦了iPhone默认的热点名称?如何更改iPhone上的热点名称
  • 【数据库审计】2023年数据库审计厂家汇总
  • C#WPF StackPanel布局及Border边框应用实例
  • RabbitMQ-第四种交换机类型
  • Redis AOF重写原原理
  • es6.x和es7.x如何创建索引?
  • 《DevOps 精要:业务视角》- 读书笔记(三)
  • C语言——文件操作_学习笔记
  • cap分布式理论
  • asp.net core 如何统一json序列化格式
  • DALL·E 3 ChatGPT-4的梦幻联动
  • linux,write:xxx has messages disabled 与 Ubuntu多用户同时登录的问题 ubuntu 20.04