?
? ????? PHP ??? ???? ??? ?? ??
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
LOCK TABLE獲取一個(gè)表級鎖,必要時(shí)等待任何沖突的鎖釋放。 如果聲明了NOWAIT,那么LOCK TABLE并不等待它所需要的鎖:如果無法立即獲取該鎖,那么該命令退出并且發(fā)出一個(gè)錯(cuò)誤信息。如果成功獲取了這個(gè)鎖,那么它就會(huì)在當(dāng)前事務(wù)的余下部分一直保持。 沒有UNLOCK TABLE命令;鎖總是在事務(wù)結(jié)尾釋放。
在為那些引用了表的命令自動(dòng)請求鎖的時(shí)候,PostgreSQL總是盡可能使用最小限制的鎖模式。 LOCK TABLE是為你在需要更嚴(yán)格的鎖的場合提供的。 例如,假設(shè)一個(gè)應(yīng)用在"讀已提交"隔離級別上運(yùn)行事務(wù), 并且它需要保證在表中的數(shù)據(jù)在事務(wù)的運(yùn)行過程中都存在。要實(shí)現(xiàn)這個(gè)目的, 你可以在查詢之前對表使用SHARE鎖模式進(jìn)行鎖定。 這樣將保護(hù)數(shù)據(jù)不被并發(fā)修改并且為任何更進(jìn)一步的對表的讀操作提供實(shí)際的當(dāng)前狀態(tài)的數(shù)據(jù), 因?yàn)?tt class="LITERAL">SHARE鎖模式與任何寫操作需要的ROW EXCLUSIVE模式?jīng)_突, 并且你的LOCK TABLE name IN SHARE MODE語句將等到所有當(dāng)前 持有ROW EXCLUSIVE模式的鎖提交或回卷后才執(zhí)行。 因此,一旦你獲得該鎖,那么就不會(huì)存在未提交的寫操作,并且其他人只能在你釋放鎖之后才能再次獲取鎖。
如果運(yùn)行在"可串行化"隔離級別實(shí)現(xiàn)類似的效果的時(shí)候,你必須在執(zhí)行任何LOCK TABLE或數(shù)據(jù)修改語句之前運(yùn)行一個(gè)SELECT語句。 一個(gè)可串行化事務(wù)的數(shù)據(jù)圖像將在其第一個(gè)SELECT或者數(shù)據(jù)修改語句開始的時(shí)候凍結(jié)住。 稍后的LOCK TABLE將仍然阻止并發(fā)的寫,但它不能保證事務(wù)讀取的東西對應(yīng)最近提交的數(shù)值。
如果一個(gè)此類的事務(wù)準(zhǔn)備修改一個(gè)表中的數(shù)據(jù), 那么應(yīng)該使用SHARE ROW EXCLUSIVE鎖模式,而不是SHARE模式。 這樣就保證任意時(shí)刻只有一個(gè)此類的事務(wù)運(yùn)行。不這樣做就可能會(huì)死鎖: 當(dāng)兩個(gè)并發(fā)的事務(wù)可能都請求SHARE模式,然后試圖更改表中的數(shù)據(jù)時(shí), 兩個(gè)事務(wù)在實(shí)際執(zhí)行更新的時(shí)候都需要ROW EXCLUSIVE鎖模式,但是它們無法再次獲取這個(gè)鎖。 請注意,一個(gè)事務(wù)自己的鎖是從不沖突的,因此一個(gè)事務(wù)可以在持有SHARE模式的鎖的時(shí)候請求ROW EXCLUSIVE模式(但是不能在任何其它事務(wù)持有SHARE模式的時(shí)候請求)。為了避免死鎖, 所有事務(wù)應(yīng)該保證以相同的順序?qū)ο嗤膶ο笳埱箧i,并且,如果涉及多種鎖模式, 那么事務(wù)應(yīng)該總是最先請求最嚴(yán)格的鎖模式。
有關(guān)鎖模式和鎖定策略的更多信息,請參考Section 13.3。
要鎖定的現(xiàn)存表的名字(可以有模式修飾)。 若已聲明ONLY,則僅僅鎖定那個(gè)表。若ONLY未聲明,表 機(jī)器字表(若存在)將會(huì)被鎖。
命令LOCK TABLE a, b;等效于LOCK TABLE a; LOCK TABLE b;。 表是按照LOCK TABLE命令中聲明的順序一個(gè)接一個(gè)順序上鎖的。
鎖模式聲明這個(gè)鎖和那些鎖沖突。鎖模式在Section 13.3里描述。
如果沒有聲明鎖模式,那么使用最嚴(yán)格的模式ACCESS EXCLUSIVE模式。
聲明LOCK TABLE不去等待任何沖突的鎖釋放: 如果無法不等待理解獲取所要求的鎖,那么事務(wù)退出。
LOCK TABLE ... IN ACCESS SHARE MODE需要在目標(biāo)表上有SELECT權(quán)限。 所有其它形式的LOCK至少需要UPDATE,DELETE或 TRUNCATE權(quán)限之一。
LOCK TABLE在事物塊之外是無效的:鎖將對語句完成時(shí)仍持有。 所以PostgreSQL報(bào)告一個(gè)錯(cuò)誤,若LOCK 在一個(gè)事物塊外被使用。 使用BEGIN和COMMIT (或者ROLLBACK)來定義一個(gè)事物塊。
LOCK TABLE只處理表級的鎖,因此那些有ROW字樣的鎖都是用詞不當(dāng)。 這些模式名字通常應(yīng)該理解為用戶視圖在一個(gè)被鎖定的表中獲取行級的鎖。 同樣,ROW EXCLUSIVE模式也是一個(gè)可共享的表級鎖。 一定要記住,只要是涉及到LOCK TABLE,那么所有鎖模式都有相同的語意, 區(qū)別只是它們與哪種鎖沖突的規(guī)則。有關(guān)如何獲取一個(gè)行級鎖的信息, 請參閱Section 13.3.2和SELECT命令參考頁的FOR UPDATE/FOR SHARE子句子句信息。
演示在往一個(gè)外鍵表上插入時(shí)在有主鍵的表上使用SHARE的鎖:
BEGIN WORK; LOCK TABLE films IN SHARE MODE; SELECT id FROM films WHERE name = 'Star Wars: Episode I - The Phantom Menace'; -- Do ROLLBACK if record was not returned INSERT INTO films_user_comments VALUES (_id_, 'GREAT! I was waiting for it for so long!'); COMMIT WORK;
在執(zhí)行刪除操作時(shí)對一個(gè)有主鍵的表進(jìn)行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;
在SQL標(biāo)準(zhǔn)里面沒有LOCK TABLE,可以使用SET TRANSACTION 來聲明當(dāng)前事務(wù)的級別。PostgreSQL也支持這個(gè),參閱 SET TRANSACTION獲取詳細(xì)信息。
除了ACCESS SHARE,ACCESS EXCLUSIVE, 和SHARE UPDATE EXCLUSIVE鎖模式外,PostgreSQL 鎖模式和LOCK TABLE語句都與那些在Oracle 里面的兼容。