本文介紹了LOCK文法的簡介、參數說明以及樣本等內容。
描述
LOCK TABLE獲得一個表級鎖,必要時會等待任何衝突鎖被釋放。如果指定了NOWAIT, LOCK TABLE不會等待以獲得想要的鎖: 如果它不能立刻得到,該命令會被中止並且發出一個錯誤。一旦擷取到, 該鎖會被在當前事務中一直持有(沒有UNLOCK TABLE命令,鎖總是在事務結束時被釋放)。
當一個視圖被鎖定時,出現在該視圖定義查詢中的所有關係也將被使用同樣的鎖模式遞迴地鎖住。
在為參考資料表的命令自動擷取鎖時, PolarDB總是儘可能使用最不嚴格的鎖模式。提供LOCK TABLE是用於想要更嚴格的鎖定的情況。例如,假設一個應用運行一個READ COMMITTED 隔離等級的事務, 並且需要確保一個表中的資料在該事務的期間保持穩定。要實現這個目的, 必須在查詢之前在表上獲得SHARE鎖模式。這將阻止並發的資料更改並且確保該表的後續讀操作會看到已提交資料的一個穩定視圖, 因為SHARE鎖模式與寫入者所要求的 ROW EXCLUSIVE鎖有衝突,並且你的 LOCK TABLE name IN SHARE MODE 語句將等待,直到任何並發持有ROW EXCLUSIVE模式鎖的持有人提交或者復原。因此,一旦得到鎖, 就不會有未提交的寫入還沒有解決。更進一步,在釋放該鎖之前,任何人都不能開始。
要在運行在REPEATABLE READ或SERIALIZABLE 隔離等級的事務中得到類似的效果,你必須在執行任何 SELECT或者資料修改語句之前執行 LOCK TABLE語句。一個 REPEATABLE READ或者SERIALIZABLE事務的資料檢視將在它的第一個SELECT或者資料修改語句開始時被凍結。在該事務中稍後的一個LOCK TABLE仍將阻止並發寫 — 但它不會確保該事務讀到的東西對應於最新的已提交值。
如果一個此類事務正要修改表中的資料,那麼它應該使用 SHARE ROW EXCLUSIVE鎖模式來取代 SHARE模式。這會保證一次只有一個此類事務運行。如果不用這種模式,死結就可能出現:兩個事務可能都要求 SHARE模式,並且都不能獲得 ROW EXCLUSIVE模式來真正地執行它們的更新(一個事務所擁有的鎖不會衝突,因此一個事務可以在它持有SHARE 模式時獲得ROW EXCLUSIVE模式 — 但是如果有其他人持有SHARE模式時則不能)。為了避免死結,確保所有的事務在同樣的對象上以相同的順序獲得鎖,並且如果在一個對象上涉及多種鎖模式,事務應該總是首先獲得最嚴格的那種模式。
文法
LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]
其中 lockmode 可以是以下之一:
ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
| SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE參數說明
name:要鎖定的現有表的名稱(可以是模式限定的)。如果在表名前指定ONLY,只有該表會被鎖定。如果沒有指定ONLY,該表和它所有的後續表(如果有)都會被鎖定。在表名後可以指定來顯式地表示把後續表包括在內。命令
LOCK TABLE a, b;等效於LOCK TABLE a; LOCK TABLE b;。這些表會被按照在LOCK TABLE中指定的順序被鎖定。lockmode:鎖模式指定這個鎖和哪些鎖衝突。如果沒有指定鎖模式,則將使用最嚴格的模式
ACCESS EXCLUSIVE。NOWAIT:指定LOCK TABLE不等待任何衝突鎖被釋放:如果所指定的鎖不能立即獲得,那麼事務就會中止。
說明
LOCK TABLE ... IN ACCESS SHARE MODE要求目標表上的SELECT特權。LOCK TABLE ... IN ROW EXCLUSIVE MODE要求目標表上的INSERT、UPDATE、DELETE或TRUNCATE特權。所有其他形式的LOCK要求表級UPDATE、DELETE或TRUNCATE特權。
在該視圖上執行鎖定的使用者必須具有該視圖上相應的特權。此外視圖的擁有者必須擁有底層基關係上的相關特權,但是執行鎖定的使用者不需要底層基關係上的任何許可權。
LOCK TABLE在事務塊外部沒有用處:鎖將只保持到陳述式完成。因此如果在事務塊外部使用了LOCK,PolarDB會報告錯誤。使用 BEGIN 和 COMMIT (或者 ROLLBACK )定義事務塊。
LOCK TABLE只處理表級鎖,因此涉及到 ROW的模式名稱在這裡都是不當的。這些模式名稱應該通常被解讀為使用者在被鎖定表中擷取行級鎖的意向。還有, ROW EXCLUSIVE模式是可共用的表鎖。記住就 LOCK TABLE而言,所有的鎖模式都具有相同的語義, 只有模式的衝突規則有所不同。
樣本
在將要向外鍵表中執行插入時在主鍵表上獲得 SHARE鎖:
BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- 如果記錄沒有被返回就做 ROLLBACK
INSERT INTO films_user_comments VALUES
(_id_, 'GREAT! I was waiting for it for so long!');
COMMIT WORK;在將要執行刪除操作前在主鍵表上取 SHARE ROW EXCLUSIVE鎖:
BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM films_user_comments WHERE id IN
(SELECT id FROM films WHERE rating < 5);
DELETE FROM films WHERE rating < 5;
COMMIT WORK;