有表如下:
CREATE TABLE `test_next_key` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+----+------+
| a | b |
+----+------+
| 1 | 1 |
| 3 | 1 |
| 5 | 3 |
| 7 | 6 |
| 10 | 8 |
+----+------+
事务 A 执行如下语句
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test_next_key where b=3 for update;
+---+------+
| a | b |
+---+------+
| 5 | 3 |
+---+------+
1 row in set (0.00 sec)
mysql> insert into test_next_key select 4,2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into test_next_key select 6,5;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
select * from test_next_key where b=3 for update; 为 b 索引上 next-key locking (1,3],(3,6)
为什么 insert 4,2 被阻塞,而 insert 6,5 可成功插入?
若仅在事务 A 执行
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test_next_key where b=3 for update;
+---+------+
| a | b |
+---+------+
| 5 | 3 |
+---+------+
1 row in set (0.00 sec)
同时在事务 B 执行
mysql> insert into test_next_key select 4,2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into test_next_key select 6,5;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
事务 B 两条都插入不成功。
加锁应该没有区别,难道是优化器根据不同事务的 SQL 做了区别的对待?