Gap Locks & Next-Key Locks

目的

本文系对MySQL InnoDB中的行锁 Next-Key Lock消除幻读 的补充。文中有些细节没有涉及或者描述的不是太清楚。

InnoDB引擎的锁技术

锁的类型

1、共享锁(S)
2、排他锁(X)
3、意向共享锁(IS)
4、意向排他(IX)

锁的算法

假设有一个表:

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index1` (`age`),
  KEY `index2` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

INSERT INTO `test`.`student`(`id`, `age`, `name`) VALUES (1, 10, '10');
INSERT INTO `test`.`student`(`id`, `age`, `name`) VALUES (2, 20, '20');
INSERT INTO `test`.`student`(`id`, `age`, `name`) VALUES (3, 30, '30');

InnoDB引擎有以下几种锁的方法:

1、Record Lock

Record Lock是作用于索引记录的锁。例如

select * from student where age = 10 for update;

其他会话执行以下sql插不进去(阻塞):

INSERT INTO `test`.`student`( `age`, `name`) VALUES (10, '10');

Record Lock作用于索引记录,如果一个表连主键索引都没有,MySQL会增加一个隐藏索引。

2、Gap Lock

Gap Lock是间隙锁,作用于索引区间范围。例如:

select * from student where age between 10 and 20 for update;

其他会话执行以下sql插不进去(阻塞):

INSERT INTO `test`.`student`( `age`, `name`) VALUES (15, '15');

3、Next-Key Lock

Next-Key Lock相当于Record Lock + Gap Lock
对于student表的初始化数据而言,Next-Key lock有几下几个:

(负无穷,10]
(10,20]
(20,30]
(30,正无穷)

下面的sql除了会锁住(10,20]还会锁住(负无穷,10] (20,30]

select * from student where age between 10 and 20 for update;

其他会话执行以下sql均插不进去(阻塞):

INSERT INTO `test`.`student`( `age`, `name`) VALUES (1, '1');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (9, '9');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (10, '10');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (20, '20');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (29, '29');

但下面的sql不会阻塞:

INSERT INTO `test`.`student`( `age`, `name`) VALUES (30, '30');

测试2

select * from student where age between 15 and 16 for update;

锁定的是(10,20]范围。
其他会话执行以下sql均插不进去(阻塞):

INSERT INTO `test`.`student`( `age`, `name`) VALUES (10, '10');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (19, '19');

其他会话执行以下sql可以插入成功:

INSERT INTO `test`.`student`( `age`, `name`) VALUES (1, '1');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (9, '9');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (20, '20');

测试3

select * from student where age = 20 for update;

锁定的是:(10,20] (20,30]
其他会话执行以下sql均插不进去(阻塞):

INSERT INTO `test`.`student`( `age`, `name`) VALUES (10, '10');
INSERT INTO `test`.`student`( `age`, `name`) VALUES (20, '20');

其他会话执行以下sql可以插入成功:

INSERT INTO `test`.`student`( `age`, `name`) VALUES (30, '30');

总结

Gap Lock和Next-Key Lock存在的意义是能够防止幻读的发生。
Gap Lock和Next-key Lock发生的条件是:InnoDB引擎 & RR事务隔离级别 && 共享锁/独占锁。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个git命令,它的作用是从远程仓库(origin)获取最新的代码,但不会拉取标签(tags)。具体的命令为:git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks fetch --no-tags origin。 ### 回答2: 这是一个git fetch命令的完整形式,如下所示: git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks fetch --no-tags origin 在这个命令中,我们可以看到以下几个参数和选项的含义: 1. diff.mnemonicprefix=false:指定差异的前缀是否显示为字母缩写(如"A"代表"Added"),而不是完整单词。这个选项被设置为false,意味着显示完整单词。 2. core.quotepath=false:这个配置设置是否对路径名中的非ASCII字符进行转义。如果设置为true,则会对路径名进行引号转义。而设置为false,则不进行引号转义,而是将它们显示为它们本来的字符。 3. --no-optional-locks:这个选项指定在仓库上执行操作时是否使用文件锁(file lock)。使用文件锁可以避免多个进程同时对一个文件进行更改。但是,如果设置了--no-optional-locks,则表示取消使用这个功能。 4. fetch:这个是基本的fetch命令,用于从远程仓库中拉取代码和对象,同步到本地仓库中。 5. --no-tags:这个选项可以选择是否从远程仓库中拉取标签(tags)。如果设置为--no-tags,则不会拉取标签。 6. origin:这个参数指定了要拉取代码的远程仓库的名称。在一个本地仓库中,通常会有多个远程仓库,通过这个参数指定要拉取的远程仓库。通常,远程仓库的名称为origin。 综合起来来说,这个命令的作用是从远程仓库origin中拉取最新的代码和对象,同步到本地仓库中,并且不会拉取标签。同时,还设置了一些选项和配置,比如取消使用文件锁、显示完整单词等。这个命令通常用于将本地仓库和远程仓库保持同步。 ### 回答3: 这条命令是Git的一条基础命令,用于从远程仓库中获取最新的代码,让本地仓库与远程仓库同步。具体解释如下: - `git`:运行Git命令 - `-c diff.mnemonicprefix=false`:设置Git的配置项,将命令行工具展示的Git操作的简写替换成全称。例如“git diff”会变成“git difference”,这样更容易理解和记忆。 - `-c core.quotepath=false`:设置Git的配置项,允许用于路径名中的特殊字符不进行转义,以便更准确地显示路径。 - `--no-optional-locks`:防止Git锁定服务器上的文件,使Git能够以后台模式运行,而不会在更新文件时锁定整个项目。 - `fetch`:从远程仓库中获取最新的代码,但不进行合并。 - `--no-tags`:不进行标签同步,只获取分支信息。 - `origin`:指定从哪个远程默认仓库获取代码,并将其与本地相应分支合并。 总的来说,这条命令的意思是,在不锁定服务器上的文件的情况下,从指定的远程默认仓库获取最新的代码,但不进行标签同步,只获取分支信息,并将其与本地相应分支合并。通常情况下,使用这条命令可以使本地仓库与远程仓库保持同步,以便在开发过程中获取最新的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值