RR下的mysql innodb引擎下一键锁定问题

时间:2019-12-02 12:21:38

标签: mysql innodb

我在学习mysql innodb引擎的下一键锁定(在Reapeatable Read级别下)时遇到问题。

这是我的表结构和表数据。

CREATE TABLE `o` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `a` int(10) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `idx_a` (`a`)
    ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8

    +----+------+
    | id | a    |
    +----+------+
    |  1 |    1 |
    |  3 |    1 |
    |  5 |    3 |
    |  7 |    6 |
    | 10 |    8 |
    +----+------+

我将正常索引添加到字段a,然后插入一些数据。 我开始进行第一笔交易(我们称为trx1)并运行以下命令:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from o where a=3 for update;
+----+------+
| id | a    |
+----+------+
|  5 |    3 |
+----+------+
1 row in set (0.00 sec)

我认为当我运行select * from o where a=3 for update时,mysql将基于下一键机制锁定(1,3],(3,6)。 接下来,我开始第二笔交易(我们称为trx2)并运行以下命令:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from o where a=5 for update;
Empty set (0.12 sec)

让我感到惊讶的是trx2为什么成功执行了命令select * from o where a=5 for update。因为我认为trx1锁定了5,trx2会阻塞直到trx1提交。

如果有人能回答我,我将非常感激!

1 个答案:

答案 0 :(得分:0)

经过几天的学习,我终于解决了。 trx1:select * from o where a=3 for update;将使用间隙锁定来锁定(1,6)。 trx2:select * from o where a=5 for update;将使用间隙锁定来锁定(3,6)。 间隙锁与间隙锁兼容!所以trx2不会阻塞。