锁列表

  • 共享与列排他锁
  • 意向锁
  • 记录锁
  • 间隙锁
  • Next-Key锁
  • 插入意向锁
  • AUTO-INC锁

这次我们只来讨论和实验意向锁。

间隙锁

间隙锁也是锁的索引记录,锁住间隙中不存在的值。

  1. 什么是间隙锁?
    间隙锁是在索引记录之间的间隙上的锁,或者在查询的第一条索引记录之前或最后一条索引记录之后的间隙上的锁。
    间隙锁通过锁住一个范围,如果其他事务想要在这个范围内插入该范围不存在的数据时就会被阻塞。

  2. 间隙锁可以用来做什么?
    InnoDB的可重复读事务隔离级别在查询使用了非唯一索引或主键时,InnoDB会使用间隙锁来阻止阻塞其他事务在间隙之间的插入。

  3. 间隙锁分类
    间隙锁可以分为间隙共享锁(gap S-lock)和间隙排它锁(gap X-lock)。
    间隙锁支持在不同事务可以在同一间隙添加间隙共享锁和间隙排他锁。

  4. 间隙锁示例
    间隙是一个范围,以下SQL都会使用间隙锁:

  5. 使用BETWEEN查询一个范围

select * from sys_user where age between 1 and 20 for update;
  1. 使用等值查询一个范围(前提:age非主键或唯一索引)
    就算一个查询是等值查询,但是查询范围是非主键或唯一索引,那么这个查询也会使用一个gap1来锁住索引节点。
select * from sys_user where age=1 for update;

实验

以下实验基于MySQL 8.0.x版本。
建表语句:

CREATE TABLE `sys_user` ( `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '姓名',
`name_pinyin` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '姓名拼音',
`id_card` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '身份证号',
`phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '手机号',
`age` int(11) NOT NULL DEFAULT 1 COMMENT '年龄',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_idx_id_card` (`id_card`) USING BTREE COMMENT '唯一索引-身份证号',
KEY `idx_phone_name` (`phone`,`name`) USING BTREE COMMENT '普通索引-手机号' ) ENGINE=InnoDB AUTO_INCREMENT=3495 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户'

表结构:

MySQL [employees]> desc sys_user;
+-------------+--------------+------+-----+---------+----------------+
| Field          | Type          | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id              | int             | NO   | PRI | NULL    | auto_increment |
| name         | varchar(10)   | NO   |      | NULL    |                |
| name_pinyin | varchar(255) | NO   |     | NULL    |                |
| id_card       | varchar(255) | NO   | UNI | NULL    |                |
| phone        | varchar(20)   | YES  | MUL | NULL    |                |
| age           | int(1)           | NO  |        | 1         |                |
+-------------+--------------+------+-----+---------+----------------+
5 rows in set (0.25 sec)

索引结构:
age字段有索引。
大家可以在where条件上没有索引的字段上尝试一下间隙锁。

使用间隙锁锁定间隙

  1. 间隙锁区间之内插入记录
    事务A,使用间隙锁锁定4000~5000之间的记录
begin;
select * from sys_user where age between 4000 and 5000 for update;

事务B,尝试在4000~5000之间插入一条id为4001的记录

begin;
insert into sys_user values (4001, '小六', 'xiaoliu', 200007510, 13000007509, 4001);

事务B在事务A执行后执行,结果事务B超时:

MySQL [employees]> begin;
Query OK, 0 rows affected (0.00 sec)MySQL [employees]> insert into sys_user values (4001, '小六', 'xiaoliu', 200007510, 13000007509, 4001);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
MySQL [employees]> 
  1. 间隙锁区间之外插入记录
    事务A,使用间隙锁锁定id<100之间的记录
begin;
select * from sys_user where age between 1 and 10 for update;

事务B,尝试在间隙之外插入一条age为11的记录:

begin
insert into sys_user (name, name_pinyin, id_card, phone, age)values ('小六', 'xiaoliu', 300000000, 13000008000, 11);

事务B可以正常插入成功。

MySQL [employees]> begin;
Query OK, 0 rows affected (0.00 sec)MySQL [employees]> insert into sys_user (name, name_pinyin, id_card, phone, age)values ('小六', 'xiaoliu', 300000000, 13000008000, 11);
Query OK, 1 row affected (0.01 sec)

间隙锁锁定区间

根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。
例如:where age=5的话并且age存在4和6的话,那么间隙锁的区间范围为(4,6);

如果查询条件中没有索引,那么InnoDB会锁定整张表中已经存在的记录和不存在的记录,基于这个特性我们要让我们的查询尽可能的使用索引或者覆盖索引。

更多区间解释可以参考:https://blog.csdn.net/bigtree_3721/article/details/73731377

注意

  1. 间隙锁可以用来防止幻读,事务隔离级别可重复读使用。
  2. 如果等值查询条件使用了主键或者唯一索引,那么不会使用间隙锁,而是直接使用记录锁。
  3. 使用读已提交事务隔离级别可以禁用间隙锁。
  4. 检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

参考

  1. https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-record-locks
  2. https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
  3. https://www.infoq.cn/article/zau0ewzsdtx9zofr6c8w
  4. https://blog.csdn.net/bigtree_3721/article/details/73731377

MySQL InnoDB中的锁-间隙锁(Gap Lock)相关推荐

  1. mysql临键锁_详解 MySql InnoDB 中的三种行锁(记录锁、间隙锁与临键锁)

    详解 MySql InnoDB 中的三种行锁(记录锁.间隙锁与临键锁) 前言 InnoDB 通过 MVCC 和 NEXT-KEY Locks,解决了在可重复读的事务隔离级别下出现幻读的问题.MVCC  ...

  2. MySQL读已提交有间隙锁吗_mysql中的幻读与间隙锁

    一.数据库隔离级别 一般来讲,数据库的隔离级别分为读未提交.读已提交(read commit,rc).可重复读(read reapeat,rr).串行化四个级别.在mysql中默认隔离级别是rr.读未 ...

  3. mysql进阶: mysql中的锁(全局锁/表锁/行锁/间隙锁/临键锁/共享锁/排他锁)

    锁在生活中处处可见,门锁,手机锁等等. 锁存在的意义是保护自己的东西不被别人偷走/修改. 在mysql中锁的意义也是一样,是为了保护自己的数据不被别人进行修改,从而导致出现脏读,幻读等问题.在学习锁的 ...

  4. MySQL 锁全集(共享锁/排它锁、记录锁/间隙锁/临键锁)

    提升工作效率利器: ‎Mac App Store 上的"Whale - 任务管理.时间.卡片.高效率" 简介:锁是计算机协调多个进程或线程并发访问某一资源变得有序的机制. 一.锁分 ...

  5. 大话:行锁 间隙锁 表锁 临键锁

    行锁 临键锁 间隙锁都是mysql里面innoDB引擎下去解决事务隔离性的一系列排他锁. 目录 行锁 ​编辑 间隙锁 表锁 临键锁 行锁 对主键或唯一索引加锁时候,mysql默认会对这一行数据默认加行 ...

  6. 详解 MySql InnoDB 中意向锁的作用

    2019独角兽企业重金招聘Python工程师标准>>> 详解 MySql InnoDB 中意向锁的作用 前言 InnoDB 支持多粒度锁(multiple granularity l ...

  7. mysql compact_在 MySQL InnoDB 中,COMPRESSED, COMPACT 和DYNAMIC 有什么区别?

    In MySQL InnoDB, what is the difference between COMPRESSED, COMPACT and DYNAMIC for ROW_FORMAT? What ...

  8. mysql事务基础+基于innodb的行锁+间隙锁+如何锁定行

    [0]README outlines are as follows : 行锁: 事务: 隔离级别: 行锁变表锁: 间隙锁: 如何锁定一行: 行锁总结: [1]行锁+事务+存储引擎基础 1.行锁: 偏向 ...

  9. 【MySQL】InnoDB中的行级锁

    行锁,也称为记录锁,顾名思义就是在记录上加的锁.但是要注意,这个记录指的是通过给索引上的索引项加锁.InnoDB 这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,In ...

  10. MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解

    MySQL/InnoDB的加锁,一直是一个面试中常问的话题.例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?我在工作过程中,也会经常用到,乐观锁,排它锁,等.于是今天就对 ...

最新文章

  1. iphone8p百度云认证_探秘百度数据工厂Pingo的多存储后端数据联合查询技术
  2. 实现 Android 应用在开机时自启动
  3. Bit-Z生态联盟正式上线 开启全球加密货币市场新征程
  4. Android 开发工具类 02_DensityUtils
  5. hive olap 数据仓库_数据仓库系统的实现和使用(含OLAP重点讲解)
  6. REM,你这磨人的小妖精!
  7. bullet HashMap 内存紧密的哈希表
  8. java 实现微博,QQ联合登录
  9. 潜在狄利克雷分配(Latent Dirichlet Allocation,LDA)
  10. LeetCode 1310. 子数组异或查询(前缀异或)
  11. android jni framework,Android Framework层的JNI机制(二)
  12. Android 系统性能优化(53)---功耗优化battery-historian V2.0的数据获取
  13. linux期中测试答案 版本号,Linux认证测试题含答案
  14. C++ 函数参数入栈方式与调用约定
  15. storm中worker、executor、task之间的关系
  16. javatodo框架中怎么配置路由
  17. (最通俗易懂的)目标跟踪MOSSE、KCF
  18. 使用Excel和Tableau分析淘宝母婴产品上新策略
  19. 推荐一款十分强大的富文本编辑器
  20. 动态修改窗口标题和类名

热门文章

  1. 拓扑排序算法原理及Java代码实现
  2. 如何在ubuntu-1804中增加swapfile
  3. QGIS获取OSM地图矢量数据
  4. Kotlin教程(一)基础
  5. kindle文件转PDF文件
  6. Python读写excel练习_去除excel中乱码行,并添加列
  7. Ubuntu系统实现简单c语言编程
  8. 直播中不可缺少的一环-rtmp直播推流
  9. ESP8266-WIFI模块配置
  10. TestStand版本切换注意事项(重启电脑)