我已经阅读并测试了 MySQL 的 InnoDB 中的行级锁,但我仍然很难说“我知道 MySQL 中的锁是如何工作的”!
这是我的测试数据:
mysql> select * from lockable;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
| 4 | B | A |
| 5 | B | B |
| 6 | B | C |
| 7 | C | A |
| 8 | C | B |
| 9 | C | C |
+----+----+----+
9 rows in set (0.00 sec)
为了测试 MySQL 关于行级锁的行为,我打开了两个终端并连接到 MySQL。我要命名它们mysql1>
和mysql2>
。这是我在第一个终端上执行的:
mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable WHERE c1 = "A" FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
+----+----+----+
3 rows in set (0.00 sec)
然后在第二个终端上:
mysql2> SELECT * FROM lockable WHERE c1 = "B" FOR UPDATE;
令我惊讶的是,上面的查询将被第一个查询阻止!所以我回滚了第一个终端并重新开始:
mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable LIMIT 3 FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
+----+----+----+
3 rows in set (0.00 sec)
然后在第二个终端上:
mysql2> SELECT * FROM lockable WHERE LIMIT 6,1 FOR UPDATE;
第二个终端再次被第一个终端阻塞!是否存在并非表的所有记录都被锁定的情况?如果不是,为什么这称为“行级锁定”?