PostgreSQL鎖級別及什么操作獲取什么鎖


表級鎖

大多數的表級鎖是由內置的 SQL 命令獲得的,但他們也可以通過鎖命令來明確獲取。可使用的表級鎖包括:

訪問共享(ACCESS SHARE) - SELECT 命令可在查詢中引用的表上獲得該鎖。一般規則是所有的查詢中只有讀表才獲取此鎖。
行共享(ROW SHARE) - SELECT FOR UPDATE 和 SELECT FOR SHARE 命令可在目標表上獲得該鎖(以及查詢中所有引用的表的訪問共享鎖)。
行獨占(ROW EXCLUSIVE) - UPDATE、INSERT 和 DELETE 命令在目標表上獲得該鎖(以及查詢中所有引用的表的訪問共享鎖)。 一般規則是所有修改表的查詢獲得該鎖。
共享更新獨占(SHARE UPDATE EXCLUSIVE) - VACUUM(不含FULL),ANALYZE,CREATE INDEX CONCURRENTLY,和一些 ALTER TABLE 的命令獲得該鎖。
共享(SHARE) - CREATE INDEX 命令在查詢中引用的表上獲得該鎖。
共享行獨占(SHARE ROW EXCLUSIVE) - 不被任何命令隱式獲取。
排他(EXCLUSIVE) - 這個鎖模式在事務獲得此鎖時只允許讀取操作並行。它不能由任何命令隱式獲取。
訪問獨占(ACCESS EXCLUSIVE) - ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,CLUSTER 和 VACUUM FULL 命令在查詢中引用的表上獲得該鎖。此鎖模式是 LOCK 命令的默認模式。
重要的是要知道,所有這些鎖都是表級鎖,即使它們名稱里有行(ROW)字。

每個鎖模式的最重要的信息是與彼此沖突的模式列表。在同一時間同一個表中,2 個事務不能同時保持相沖突的鎖模式。事務永遠不會與自身發生沖突。 非沖突的鎖可以支持多事務並發。同樣重要的是要知道有的模式和自身沖突。一些鎖模式在獲得后會持續到事務結束。但如果鎖是在建立一個保存點后獲得,保存點回滾后鎖會被立刻釋放

 

行級鎖

在 Postgres 9.1 和 9.2 有兩種行級鎖模式,但在 Postgres 9.3 和 9.4 有四種行級鎖模式。

Postgres 不會記住修改的行在內存中的任何信息,所以一次鎖定的行的數目沒有限制。然而,鎖定一行可能會導致磁盤寫入,例如,SELECT FOR UPDATE 修改選定的行並標記它們鎖定,所以會導致磁盤寫入。

Postgres 9.1 和 9.2 中的行級鎖

在這兩種版本中,只有 2 種行級鎖:排他或共享鎖。當行更新或刪除時,會自動獲得排他行級鎖。行級鎖不阻止數據查詢,它們只阻止同一行寫入。 排他行級鎖可由 SELECT FOR UPDATE 命令明確獲得,即使行沒有實際更改。

共享行級鎖可由 SELECT FOR SHARE 命令獲得。一個共享鎖並不阻止其他事務獲取同樣的共享鎖。然而,當任何其他事務持有共享鎖時,事務的更新、刪除或排他鎖都不被允許。


更新(FOR UPDATE) - 這種模式導致 SELECT 讀取的行的更新被鎖定。這可以防止它們被其他事務鎖定,修改或刪除。即嘗試 UPDATE、DELETE、SELECT FOR UPDATE、SELECT FOR NO KEY UPDATE、SELECT FOR SHARE 或 SELECT FOR KEY SHARE 的其他事務將被阻塞。刪除一行,更新一些列也可以獲得到此種鎖模式(目前的列集是指那些具有唯一索引,並且可被用作外鍵 - 但將來這可能會改變)。
無鍵更新(FOR NO KEY UPDATE) - 這種模式與 FOR UPDATE 相似,但是更弱 - 它不會阻塞SELECT FOR KEY SHARE 鎖模式。它通過不獲取更新鎖的 UPDATE 命令獲得。
共享(FOR SHARE) - 這種模式與無鍵更新鎖類似,除了它可以獲取共享鎖(非排他)。一個共享鎖阻止其他事務在這些行上進行 UPDATE,DELETE,SELECT FOR UPDATE 或 SELECT FOR NO KEY UPDATE 操作,但並不阻止它們進行 SELECT FOR SHARE 或 SELECT FOR KEY SHARE。
鍵共享(FOR KEY SHARE)- 行為類似於共享,但該鎖是較弱的:阻止了 SELECT FOR UPDATE,但不阻止 SELECT FOR NO KEY UPDATE。一個鍵共享鎖阻止其他事務進行 DELETE 或任何更改該鍵值的 UPDATE,但不妨礙任何其他 UPDATE、SELECT FOR NO KEY UPDATE、SELECT FOR SHARE 或者SELECT FOR KEY SHARE。

 

 

select * from test for update; 

這個鎖會讓查詢到的數據不會被更新,刪除,或者被其他事務鎖定,但是可以查詢;

 

lock table test;

在一個事務中執行,會讓別的事務無法使用該表;

 

pg是默認讀已提交,即使是前面未提交的事務,在本事務中途提交,也能讀取已經提交的數據。—在同一個事務,兩次讀取,允許獲取不一樣的數據。即不可重復讀。

 

可重復讀的隔離級別更高,最后是串行化。

 

插入更新刪除獲取的是表的row exclusive鎖,允許查詢。 創建索引會獲取的是share鎖,不允許插入數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM