PostgreSQL7.0手冊-用戶手冊-19. SQL命令-LOCK
2019-09-08 23:33:13
供稿:網友
LOCK
名稱
LOCK ― 在事務中顯式地鎖定一個表
語法
LOCK [ TABLE ] name
LOCK [ TABLE ] name IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE
LOCK [ TABLE ] name IN SHARE ROW EXCLUSIVE MODE
輸入
name
要鎖定的現存的表.
ACCESS SHARE MODE
注意:這個鎖模式對被查詢的表自動生效。
這是最小限制的鎖模式,只與 ACCESS EXCLUSIVE 模式沖突。它用于保護被查詢的表免于被并行的 ALTER TABLE, DROP TABLE 和 VACUUM 對同一表操作的語句修改?!?
ROW SHARE MODE
注意:任何 SELECT FOR UPDATE 語句執行時自動生效。因為它是一個共享鎖,以后可能更新為 ROW EXCLUSIVE 鎖。
與 EXCLUSIVE 和 ACCESS EXCLUSIVE 鎖模式沖突?!?
ROW EXCLUSIVE MODE
注意:任何 UPDATE, DELETE, INSERT 語句執行時自動生效。
與 SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式沖突。
SHARE MODE
注意:任何 CREATE INDEX 語句執行時自動附加。
與 ROW EXCLUSIVE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式沖突。這個模式防止一個表被并行更新?!?
SHARE ROW EXCLUSIVE MODE
注意:這個模式類似 EXCLUSIVE MODE,但是允許其他事務的 SHARE ROW 鎖.
與 ROW EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式沖突?!?
EXCLUSIVE MODE
注意:這個模式同樣比 SHARE ROW EXCLUSIVE 更有約束力;它阻塞所有并行的 SELECT FOR UPDATE 查詢。
ROW SHARE,ROW EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式沖突。
ACCESS EXCLUSIVE MODE
注意: 由語句 ALTER TABLE,DROP TABLE,VACUUM 執行時自動生效。這是最嚴格的約束鎖,它與所有其他的鎖模式沖突并且保護一個被鎖定的表不被任何其他并行的操作更改。
注意: 一個不合格的 LOCK TABLE 同樣要求這個鎖模式(例如,一條沒有顯式鎖模式選項的命令)。
輸出
LOCK TABLE
成功鎖定后的返回.
ERROR name: Table does not exist.
如果 name 不存在,返回此信息.
描述
Postgres 在可能的情況下盡可能使用最小約束的鎖模式。LOCK TABLE 在你需要時提供更有約束力的鎖?!?
RDBMS 鎖定使用下面術語:
EXCLUSIVE
排它鎖,防止其他(事務)鎖的產生.
SHARE
允許其他(事務)共享鎖.表面 EXCLUSIVE 鎖.
ACCESS
鎖定表結構.
ROW
鎖定獨立的行.
注意:如果沒有聲明 EXCLUSIVE 或 SHARE,假設為 EXCLUSIVE.鎖存在于事務周期內.
例如,一個應用在 READ COMMITED 隔離級別上運行事務,并且它需要保證在表中的數據在事務的運行過程中都存在。要實現這個你可以在查詢之前對表使用 SHARE 鎖模式進行鎖定。這樣將保護數據不被并行修改并且為任何更進一步的對表的讀操作提供實際狀態的數據,因為 SHARE 鎖模式與任何寫操作需要的 ROW EXCLUSIVE 模式沖突,并且你的 LOCK TABLE name IN SHARE MODE 語句將等到所有并行的寫操作提交或回卷后才執行?!?
注意:當在 SERIALIZABLE 隔離級別運行事務,而且你需要讀取真實狀態的數據時,你必須在執行任何 DML 語句(這時事務定義什么樣的并行修改對它自己是可見的)之前運行一個 LOCK TABLE 語句。
除了上面的要求外,如果一個事務準備修改一個表中的數據,那么應該使用 SHARE ROW EXCLUSIVE 鎖模式以避免死鎖情況(當兩個并行的事務試圖以 SHARE 模式鎖住表然后試圖更改表中的數據時,兩個事務(隱含的)都需要 ROW EXCLUSIVE 鎖模式,而此模式與并行的 SHARE 鎖沖突)?!?
繼續上面的死鎖(兩個事務彼此等待)問題,你應該遵循兩個通用的規則以避免死鎖條件:
事務應該以相同的順序對相同的對象請求鎖。
例如,如果一個應用更新行 R1 然后更新行 R2(在同一的事務里),那么第二個應用如果稍后要更新行 R1 時不應該更新行 R2(在同一事務里)。相反,它應該與第一個應用以相同的順序更新行 R1 和 R2?!?
事務請求兩個互相沖突的鎖模式的前提:其中一個鎖模式是自沖突的(也就是說,一次只能被一個事務持有)。如果涉及多種鎖模式,那么事務應該總是最先請求最嚴格的鎖模式。
這個規則的例子在前面的關于用 SHARE ROW EXCLUSIVE 模式取代 SHARE 模式的討論中已經給出了。
注意: Postgres 不檢測死鎖,并將回卷至少一個等待的事務以解決死鎖。
注意
LOCK 是 Postgres 語言擴展.
除了ACCESS SHARE/EXCLUSIVE 鎖模式外,所有其他 Postgres 鎖模式和 LOCK TABLE 語句都與那些在 Oracle 里面的兼容?!?
LOCK 只在事務內部使用.
用法
演示在往一個外鍵表上插入時在有主鍵的表上使用 SHARE 的鎖:
BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- 如果記錄沒有返回則回卷
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;
兼容性
SQL92
在 SQL92 里沒有 LOCK TABLE ,可以使用 SET TRANSACTION 來聲明當前事務的級別.我們也支持這個,參閱 SET 獲取詳細信息。