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。
答案 0 :(得分:0)
是的,这是间隙锁定。
这两个插入实际上并没有尝试插入相同的值,因为二级索引还在末尾存储了主键的副本(如果引用的列多于索引,则索引查找如何找到原始行。索引)。
在索引b
中,有问题的行将按此排序。
b a
60, 50
90, 4
90, 45
90, 46
从这个例子中,你可以看到(4,90)属于(60,50)之后的差距,但是(46,90)不在那个差距中。