分享MySQL记录锁、间隙锁、临键锁小案例演示,你学废了吗
生成间隙(gap)锁、临键(next-key)锁的前提条件 是在 RR 隔离级别下 。有关MySQL记录锁、间隙(gap)锁、临键锁(next-key)锁的一些理论知识之前有写过,详细内容可以看这篇文章 一文详解MySQL的锁机制
这篇主要通过小案例来对记录锁、间隙(gap)锁、临键(next-key)锁做一个更好的理解 。
这里先给出结论,再来用实际例子证明
1、当使用唯一索引来等值查询的语句时, 如果这行数据存在,不产生间隙锁,而是记录锁 。
2、当使用唯一索引来等值查询的语句时, 如果这行数据不存在,会产生间隙锁 。
3、当使用唯一索引来范围查询的语句时,对于满足查询条件但不存在的数据产生间隙(gap)锁,如果查询存在的记录就会产生记录锁,加在一起就是临键锁(next-key)锁 。
4、当使用普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;
5、在没有索引上不管是锁住单条,还是多条记录,都会产生表锁;间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,这是为了防止出现 幻读 现象;
间隙的范围?
根据检索条件向下寻找最靠近检索条件的记录值A作为左区间,向上寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B] 左开右闭 。
接下来我们开始来验证以上结论
一、数据和环境准备1、创建表和数据
CREATE TABLE `t` (`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',`age` int NOT NULL COMMENT '年龄',`mobile` int DEFAULT NULL COMMENT '手机号',`name` varchar(8)DEFAULT NULL COMMENT '名称',PRIMARY KEY (`id`),KEY `index_age` (`age`)) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
id为主键(唯一索引)、age是普通索引、mobile没有加索引同时插入数据如下 。

文章插图
在进行测试之前,我们先来看看t表中存在的隐藏间隙:

文章插图
(-∞, 1]
(1, 4]
(4, 7]
(7, +supernum]
(其中supernum是数据库维护的最大的值 。为了保证间隙锁都是左开右闭原则 。)
2、关闭事务默认提交
mysql> SHOW VARIABLES LIKE 'autocommit';+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit| ON|+---------------+-------+1 row in set (0.00 sec)
结果显示,autocommit 的值是 ON,表示系统开启自动提交模式 。在 MySQL 中,可以使用 SET autocommit 语句设置事务的自动提交模式,语法格式如下:
SET autocommit = 0|1|ON|OFF;
对取值的说明:值为 0 和值为 OFF:关闭事务自动提交 。如果关闭自动提交,用户将会一直处于某个事务中,只有提交或回滚后才会结束当前事务,重新开始一个新事务 。
值为 1 和值为 ON:开启事务自动提交 。如果开启自动提交,则每执行一条 SQL 语句,事务都会提交一次 。
二、唯一索引示例1、等值查询且数据存在示例

文章插图
事务A 等值查询id=4,因为id是主键,同时是等值查询存在该记录,所以只会在id=4这条记录上加记录锁,不会加间隙锁 。
事务B 等值查询id=5,没有锁冲突,所以查询正常,不会堵塞 。(如果事务B 等值查询id=4,因为事务A加了记录锁,所以会堵塞)
2、等值查询且数据不存在示例

文章插图
事务A 等值查询id=5,因为查询记录不存在,所以无法加记录锁,但这里会存在一个(5,7]的间隙锁 。
事务B 插入一条id=6的数据,因为上面存在了(5,7]的间隙锁,所以会堵塞 。
3、范围查询示例

文章插图
事务B 插入一个id=6、age=6的数据,因为age值在上面临键锁,范围内,所以也会堵塞 。
事务B 插入一条id=6的数据,因为上面存在了(4,+supernum]的临键(next-key)锁,所以会堵塞 。
如果 事务B 是更新 id=7 的记录,同样会堵塞 。
三、普通索引示例1、等值查询值

推荐阅读
- 百万级数据下的mysql深度解析
- Mysql数据库tinyint,int,bigint,char,varchar究竟用哪个?
- 黑肌玉露怎么养,草玉露怎么养才饱满
- Win下部署多个MySQL数据库实例
- MySQL中常用的15个查询子句
- 分享新手自媒体的创作过程,怎么才能提高流量权益?
- 15个MySQL常用基本SQL语句
- 展现量60多万跌至几十,我走过的弯路经验分享给你们
- 数据库迁移有什么技巧?|分享强大的database迁移和同步工具
- 怎么在电脑上录制高清视频?轻松实现高清录制的教程分享