【问题标题】:mysql innodb engine next-key lock question under RRRR下mysql innodb engine next-key lock问题
【发布时间】:2019-12-02 12:21:38
【问题描述】:

我在学习mysql innodb引擎next-key lock时遇到一个问题(在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 将基于 next-key 机制锁定 (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提交。

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

【问题讨论】:

    标签: mysql innodb


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      相关资源
      最近更新 更多