我有兩個簡單的查詢,一個是讀取表,一個是更新表。如何在更新查詢執行時間鎖定選擇查詢的讀取。現在在 MySQL InnoDB 中,我注意到寫入/更新預設是鎖定的,但讀取/選擇在事務之前取得舊資料。
我嘗試在更新查詢中使用事務,然後 SELECT ... FOR UPDATE - 在事務之外 - 但它似乎沒有成功。另外,出於測試目的,我想知道如何減慢 UPDATE 查詢的速度。我遇到了 SLEEP(X),但我不知道如何在更新查詢中實現它。
SELECT ... FOR UPDATE
如何讓每個查詢等待讀取/寫,直到寫入完成。
使用READ-COMMITTED交易將查看最新提交的交易。更改,並使用SELECT ... LOCK IN SHARE MODE 將使讀取阻塞,直到提交任何未完成的更新。
READ-COMMITTED
SELECT ... LOCK IN SHARE MODE
試試這個。在一個畫面中,啟動事務和更新。不需要 SLEEP(),只是不提交交易。 UPDATE 建立的鎖定將繼續存在,直到您提交為止。
BEGIN; UPDATE MyTable SET something = '1234' WHERE id = 3;
先不要提交。
同時,在第二個畫面中,將交易隔離設定為讀取提交交易。無需啟動明確事務,因為 InnoDB 查詢使用事務,即使它是自動提交的。
SET tx_isolation='READ-COMMITTED'; SELECT * FROM MyTable WHERE id = 3 LOCK IN SHARE MODE; <hangs>
共享模式中的鎖定使其等待,因為仍有一個由更新創建的未完成的排他鎖。
在第一個畫面:
COMMIT;
在第二個畫面中,瞧!阻塞讀取將解除阻塞,您可以立即看到 UDPATE 的結果,而無需刷新交易。
使用
READ-COMMITTED
交易將查看最新提交的交易。更改,並使用SELECT ... LOCK IN SHARE MODE
將使讀取阻塞,直到提交任何未完成的更新。試試這個。在一個畫面中,啟動事務和更新。不需要 SLEEP(),只是不提交交易。 UPDATE 建立的鎖定將繼續存在,直到您提交為止。
先不要提交。
同時,在第二個畫面中,將交易隔離設定為讀取提交交易。無需啟動明確事務,因為 InnoDB 查詢使用事務,即使它是自動提交的。
共享模式中的鎖定使其等待,因為仍有一個由更新創建的未完成的排他鎖。
在第一個畫面:
在第二個畫面中,瞧!阻塞讀取將解除阻塞,您可以立即看到 UDPATE 的結果,而無需刷新交易。