今天,看了一篇博文,我复现原博文的SQL,有一个知识点我理解不了,但是我暂时又不会。先记下来,等过几天有时间在研究研究。
复现步骤:
在MySQL版本5.7.18,事务隔离级别是REPEATABLE-READ
建表语句:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(11) NOT NULL,
`v1` int(11) NULL DEFAULT NULL,
`v2` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_v1`(`v1`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of test
-- ----------------------------
INSERT INTO `test` VALUES (1, 1, 0);
INSERT INTO `test` VALUES (2, 3, 1);
INSERT INTO `test` VALUES (3, 4, 2);
INSERT INTO `test` VALUES (5, 5, 3);
INSERT INTO `test` VALUES (7, 7, 4);
INSERT INTO `test` VALUES (10, 9, 5);
SET FOREIGN_KEY_CHECKS = 1;
1,在navicat中,第一个窗口中
start transaction;
update test set v2 = 9 where v1 = 5;
按道理说,我的next-key lock会锁定v1的(4,7),任何其他事务只要不在这个区间操作,就不会发生“锁等待的情况”。
2,在第二个窗口中
start transaction;
update test set v1 =2 where v2 = 5;
这个修改v1又不在(4,7)范围内,什么连边界都没有沾上边,为什么执行不了???
解答思路:
经过思考了,我发现我刚才的思路有问题。我总是想着第二个窗口的v1一定和第一个窗口的v1因为间隙锁而造成了锁等待现象,也是原博文中给的错误指引。
实际结果应该是:在第二个窗口中,v2作为更新条件,导致锁表,但是第一个表锁住了2行了,所以第二个窗口中事务,锁表失败,发生了锁等待现象。
不过无论如何,我从原博中学习了很多,感谢原博主。