0
我已經閱讀並測試了MySQL的InnoDB中的行級鎖,但是我仍然發現實際上很難說「我知道鎖在MySQL中的工作方式」!哪些記錄與MySQL的'SELECT ... FOR UPDATE'鎖定
這裏是我的測試數據:
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;
同樣的2端通過第一個阻擋!是否有任何情況下表格的所有記錄都未被鎖定?如果不是爲什麼這被稱爲「行級鎖定」?
不相關但是:在標準SQL中雙引號*僅用於標識符。要指定字符串文字,請使用單引號。 '「B」是一個列名,但「B」是一個字符串值。 MySQL接受錯誤和正確的文字,但如果您想要使用不同的DBMS,則應遵守標準兼容的方式。關於你的問題:我*認爲*(不知道)你被MySQL的「gap gap」擊中了其他行而不是你請求的行。你也可能想嘗試一個真正的'更新',而不是。也許'select .. for update'行爲有所不同。 –
感謝這篇文章,我從現在開始嘗試使用'''而不是''' – Mehran
Btw:你的例子在Postgres和Oracle中按預期工作 –