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 の動作をテストするために、2 つのターミナルを開き、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)
次に、2番目の端末で:
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)
次に、2番目の端末で:
mysql2> SELECT * FROM lockable WHERE LIMIT 6,1 FOR UPDATE;
再び、2 番目の端末が 1 番目の端末によってブロックされました。テーブルのすべてのレコードがロックされていないシナリオはありますか? そうでない場合、これが「行レベルのロック」と呼ばれるのはなぜですか?