差距锁定与否

时间:2018-05-24 08:00:04

标签: mysql

CREATE TABLE `z` (
  `a` int(11) NOT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`a`),
  KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `test`.`z` (`a`, `b`) VALUES (1, 1);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (3, 1);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (5, 3);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (7, 6);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (10, 8);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (20, 30);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (50, 60);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (45, 90);
INSERT INTO `test`.`z` (`a`, `b`) VALUES (2, 99);

transaction_isolation = REPEATABLE-READ
tx_isolation = REPEATABLE-READ

第1节

开始;

从z中选择*,其中b = 60表示更新;

会话2

开始;

插入z select 4,90; / *为什么这不能插入? * /

ERROR 1205(HY000):超出锁定等待超时;尝试重新启动交易

插入z select 46,90; / *但这可以插入吗? * /

查询正常,1行受影响(0.00秒)

记录:1个重复:0个警告:0

如上所述: 一个可以插入,但另一个不能。它们都是相同的价值 - 90。

1 个答案:

答案 0 :(得分:0)

是的,这是间隙锁定。

这两个插入实际上并没有尝试插入相同的值,因为二级索引还在末尾存储了主键的副本(如果引用的列多于索引,则索引查找如何找到原始行。索引)。

在索引b中,有问题的行将按此排序。

b   a
60, 50
90, 4
90, 45
90, 46

从这个例子中,你可以看到(4,90)属于(60,50)之后的差距,但是(46,90)不在那个差距中。