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

记录锁,间隙锁,Next-Key Lock

记录锁,间隙锁,Next-Key Lock

  • mysql的锁机制
    • 一、InnoDB行锁的种类
      • 1、记录锁(Record Lock)
        • (1)不加索引,两个事务修改同一行记录
        • (2)不加索引,两个事务修改同一表非同行记录
        • (3)加索引,修改同一行记录,不行
        • (4)加索引,修改同表的不同行,可以修改
      • 2、间隙锁(GAP Lock)
      • 3、记录锁和间隙锁的组合(next-key lock)

mysql的锁机制

  • 数据库锁机制简单来说,就是数据库为了保证数据的一致性,使各种 共享资源 在被访问时变得 有序而设计 的一种规则。
  • MysQL的锁机制比较简单最著的特点是不同的存储引擎支持不同的锁机制。 InoDB支持行锁,(有时也会升级为表锁)MyISAM只支持表锁。
  • 表锁 的特点就是开销小、加锁快,不会出现死锁。锁粒度大,发生锁冲突的概率小,并发度相对低。
  • 行锁 的特点就是开销大、加锁慢,会出现死锁。锁粒度小,发生锁冲突的概率高,并发度高。

今天我们讲锁主要从InnoDB引擎来讲,因为它既支持行锁、也支持表锁。

看完看笔记可以看下这篇博客,非常优秀:
mysql 索引间隙锁_关于mysql innodb间隙锁的一些思考

或者这个间隙锁
一分钟了解Mysql的间隙锁——《深究Mysql锁》

一、InnoDB行锁的种类

  • InnoDB默认的事务隔离级别是RR,并且参数innodb_locks_unsafe_for_binling=0的模式下,行锁有三种。

1、记录锁(Record Lock)

在这里插入图片描述

(1)不加索引,两个事务修改同一行记录

事务一:

begin;
update teacher set teacher_no = 'T2010005' where name = 'wangsi';

事务二:

begin;
update teacher set teacher_no = 'T2010006' where name = 'wangsi';

发现卡住了:
事务一提交了,事务二才获取了。
测试我们发现第二个窗口,一直在处理中
在这里插入图片描述
并且最后会报一个超时的错误!我们把第一个窗口提交了
在这里插入图片描述
然后在执行一次第二个窗口:
在这里插入图片描述
我们发现第二个窗口就可以执行了

(2)不加索引,两个事务修改同一表非同行记录

事务一:

begin;
update teacher set teacher_no = 'T2010005' where name = 'wangsi';

事务二:

begin;
update teacher set teacher_no = 'T2010006' where name = 'sunsi';

发现卡住了:
事务一提交了,事务二才获取了。
说明锁的是表!

(3)加索引,修改同一行记录,不行

在这里插入图片描述事务一:

begin;
update teacher set teacher_no = 'T2010005' where name = 'wangsi';

事务二:

begin;
update teacher set teacher_no = 'T2010006' where name = 'wangsi';

发现卡住了:
事务一提交了,事务二才获取了。

(4)加索引,修改同表的不同行,可以修改

事务一:

begin;
update teacher set teacher_no = 'T2010008' where name = 'wangsi';

事务二:

begin;
update teacher set teacher_no = 'T2010009' where name = 'jiangsi';

我们发现也不行,那我们试试在name字段上加索引!
在这里插入图片描述
发现都可以顺利修改,说明锁的的确是行。
证明行行锁是加在索引上的,这是标准的行级锁。
所以一定要记住,行锁是加在索引上的,如果没有索引就会加到全表上!

2、间隙锁(GAP Lock)

在RR这个级别下 ,为了避免幻读,引入了间隙锁,他锁定的是记录范围,不包含记录本身,也就是不允
许在范围内插入数据。
查看隔离级别:

show variables like '%iso%';

在这里插入图片描述我们现在把表中id是4的数据改成8,然后开始测试:

begin;
SELECT * from teacher where id = 8  or id = 6 for UPDATE;

我们开启一个事务,查询一下id为8或者6的数据,按照间隙锁的条件,现在上面应该是id为(3-6),下面8就是最大的,也就是说,id从3到无穷大,这个时候都是不能插入的,go!这个地方要注意,
1.普通查询是快照读,是不会加锁的!
2.主键和唯一索引只有在where条件没有全部命中的时候才会产生间隙锁!所以我们要先去掉id字段的主键

然后打开新的窗口进行插入

begin; 
insert into teacher values (5,'zhangnan','T888888');

在这里插入图片描述
我们关闭所有窗口,插入一条为9的数据:
在这里插入图片描述
这个时候我们测试下,理论上锁定的是8到无穷大:

begin;
SELECT * from teacher where id = 10 for UPDATE;

执行sql:

begin; 
insert into teacher values (5,'zhangnan','T888888');

在这里插入图片描述
在这里插入图片描述
插入5可以,我们插入20看看

begin; 
insert into teacher values (20,'linda','T232323');
COMMIT;

在这里插入图片描述我们发现又开始卡住了!
当然我们也可以手动加上共享锁:
在这里插入图片描述
我们开始写第一个窗口语句:

BEGIN;
SELECT * from teacher where id < 8;

在这里插入图片描述
我们写第一个窗口语句:

begin; 
insert into teacher values (6,'linda','T232323');
COMMIT;

在这里插入图片描述
执行成功,第一个窗口再次执行,产生幻读
在这里插入图片描述
我们手动加上共享锁:

BEGIN;
SELECT * from teacher where id < 8 lock in share mode;

第二个窗口开始测试:

begin; 
insert into teacher values (5,'linda5','T55555');
COMMIT;

我们发现卡住了,这个地方就加上了一个1-8)的共享锁,这样也能够解决幻读的问题,但是会产生大量的数据锁定:
因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件。第二就是尽量不要用范围查询出数据,在去筛选,或者缩小查询范围!

锁的一些总结:【mysql】表锁、行锁、间隙锁、共享锁(读锁)、排他锁(写锁)、Next-Key Locks 之间的关系
如果没有索引,innodb的行锁会升级为表锁,效果和表锁一样,锁住全部索引

3、记录锁和间隙锁的组合(next-key lock)

  • 是记录锁和间隙锁的组合,当InnoDb扫描索引时会先对索引记录加上记录锁,在对索记录两边加上间隙锁。
BEGIN;
SELECT * from teacher where id = 6 or id = 8 for update;

我们发现锁定的范围是6-8,5是可以正常插入的

如果使用的是next-key lock,则5是不可以插入的,但是我们的id有唯一索引,所以next-key lock降级为了GAP Lock

InnoDB有三种行锁的算法:

  • 1,Record Lock:单个行记录上的锁。
  • 2,Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。
  • 3,Next-Key Lock:1+2,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。

在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

InnoDB行锁是通过给索引项加锁实现的,如果没有索引,InnoDB会通过隐藏的聚簇索引来对记录加锁。也就是说:如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样

相关文章:

  • 2025数学建模竞赛汇总,错过再等一年
  • 2025-02-25 学习记录--C/C++-用C语言实现删除字符串中的子串
  • ollama无法通过IP:11434访问
  • 第9章 机器学习与统计模型
  • 《OpenCV》—— 背景建模
  • 精美登录注册UI,登录页面设计模板
  • 微信小程序面试题
  • 分治算法、动态规划、贪心算法、分支限界法和回溯算法的深度对比
  • 开源堡垒机 JumpServer 社区版实战教程:发布机的配置与Website资产配置使用
  • 大模型在急性肾损伤预测及临床方案制定中的应用研究
  • 策略模式在工作中的运用
  • go语言环境下载与配置(Windows)
  • 轻松搭建:使用Anaconda创建虚拟环境并在PyCharm中配置
  • muduo网络库2
  • 滴水逆向_esp寻址
  • MySQL索引失效
  • 面试题——简述Vue 3的服务器端渲染(SSR)是如何工作的?
  • 布署elfk-准备工作
  • 【愚公系列】《Python网络爬虫从入门到精通》033-DataFrame的数据排序
  • 【QT】QLinearGradient 线性渐变类简单使用教程
  • 做网站哪个简单点/最近国内新闻
  • wordpress 暗盒/福州外包seo公司
  • 正规网站建设/关于友谊的连接
  • 新桥专业网站建设/seo学习网站
  • 世界500强企业排名 2021最新名单/泰安seo公司