1. 程式人生 > >SQLServer鎖的基礎問題探究

SQLServer鎖的基礎問題探究

SqlServer需要在執行操作前對目標資源獲取所有權,那麼久發生鎖定,是一個邏輯概念。為了保證事務的ACID特性設計的一種機制。

在多使用者併發操作資料時,為了出現不一致的資料,鎖定是必須的機制。使用鎖可保證資料一致性,但這也致使你在編碼、設計時要把鎖定考慮進去。如果鎖的數量太多,持續時間過長,對併發和系統性能都沒有好處。

在SQL Server支援的隔離級別中,級別越高,嚴格性也就越高,這就增加了阻塞甚至死鎖的機會。

鎖資源:行、頁、或者表(如果有分割槽、可能還有分割槽鎖)

鎖模式:共享鎖、排他鎖、更新鎖、意向鎖、

鎖的所有權:鎖的範圍。絕大部分鎖的範圍是事務範圍的

鎖定的元資料:使用sys.dm_tran_locks這個DMV解鎖。

SQLServer可以在使用者資料的行(RID/KEY鎖)、頁(PAGE鎖)或者表(OBJECT鎖)級別上鎖定資源。SQLServer會盡可能申請行級鎖、以便獲取最高的併發度。

SQL Server鎖住一個索引上的行時,在sys.dm_tran_locks中會顯示Key;如果是鎖住了堆表上的資料行,則會顯示RID,如果堆上有非聚集索引,實際上是鎖住了整個索引行,而不僅僅是索引鍵。當會話執行在SERIALIZABLE隔離級別下,還可能會鎖住索引行的一個範圍

根據不同的隔離級別,可以支援兩種Key鎖,如果事務的隔離級別為READ COMMITTED/REPEATABLE READ,會鎖住查詢需要的索引行,如果資料表上有聚集索引,實際的資料行在葉子節點中,顯示KEY鎖,如果表為堆表,SQL Serer會把鎖加到非聚集索引中,也叫KEY鎖,或者加在堆的資料行上,叫RID鎖

隔離級別為SERIALIZABLE,為了避免幻讀,SQL Server 會鎖住一個範圍,如果所查詢的是範圍值,那麼需要鎖住足夠的部分,確保另外一個事務不會在這個事務掃描的過程中插入值,這種說在DMV中顯示key-range鎖。

幻讀:如果事務A中有兩個相同的查詢,而且帶有了限定詞(如WHERE條件)在第一次查詢之後,會鎖住查詢所需的資料範圍,而事務B這時插入了一行滿足WHERE條件的資料,在第一次查詢中沒有這條資料,沒有鎖住,插入是成功的,當事務A進行第二次查詢時,就會出現這條新資料,於是就出現了幻讀。