RR下的mysql innodb engine next-key lock问题

标签 mysql innodb

我在学习mysql innodb engine next-key lock (under Repeatable Read level)时遇到一个问题。

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

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 提交。

如果有人能为我解答,我将不胜感激!!!

最佳答案

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

关于RR下的mysql innodb engine next-key lock问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59138844/

相关文章:

php - 需要正确的 SQL 查询

java - 使用 JDBC 连接到 Openshift 数据库

mysql - 在 MySQL InnoDB 中存储大于 max_allowed_pa​​cket 的 BLOB 的最佳方法

mysql - "query end"随机时间步长

mysql - 我的sql查询每个类别最高分的总和

mysql - 为 Rails 使用 2 个数据库 : MySQL or SQLite for Testing and Developmnet and PostgreSQL for Production

php - 使用 PHP 从 SQL 数据库中选择不同的语言

mysql - 选择列值较上一行发生变化的行、用户变量、innodb

MySQL INSERT SELECT WHERE 竞争条件

mysql - 在哪种情况下,MySQL 的 InnoDB 的 COMPACT row_format 会比 REDUNDANT 更快/更好?