sql server中意向鎖的作用


意向鎖

數據庫引擎使用意向鎖來保護鎖層次結構的底層資源,以防止其他事務對自己鎖住的資源造成傷害,提高鎖沖突檢測性能。例如,當讀取里的頁面時,在請求共享鎖(S鎖)之前,事務在表級請求共享意向鎖。這樣可以防止其他事務隨后在上獲取排他鎖(X鎖),修改整個表格。意向鎖可以提高性能,因為數據庫引擎僅在表級檢查意向鎖,確定事務是否能安全地獲取該表上的鎖,而不需要檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。

如何理解上面這句話的意思呢?我們以一個實際例子來說明。

假如有一張Student,其中包含1000條數據,測試數據如下:

create table Student
(
    id int,
    name char(30),
    constraint pk_id primary key(id)
)

--3.插入1000條記錄
SET NOCOUNT ON;
GO

DECLARE @i int;
SET @i = 1;
WHILE @i <= 1000 BEGIN
  INSERT INTO Student values(@i,'zhangsan'+cast(@i as char))
  SET @i = @i + 1;
 END;
GO

因為設置了id列為主鍵,那么sql server會自動為其添加聚集索引。假如我們使用如下語句更新表中的數據,

begin tran 
UPDATE Student SET name ='zhangsan' WHERE id=1000;

然后再查詢當前的鎖狀態,執行如下TSQL

--查看所狀態
SELECT request_session_id, resource_type, resource_associated_entity_id,
    request_status, request_mode, resource_description
    FROM sys.dm_tran_locks

其查詢結果如下圖所示:

我們可以看到在Object和Page上面加了IX鎖,而在Key上面加了X鎖,這三種類型的鎖層次結果如下圖所示:

那么在表上加一個意向排它鎖(IX)有什么用呢?假如此時有另外一個事務要求對整張表加S鎖,它需要判定能夠對這張表加這個S鎖。

  1. 如果不使用意向鎖的話,那么得遍歷Key查看是否有與S鎖沖突的鎖,而我們上面加鎖的那一條記錄剛好是最后一條,那么就得遍歷所有數據。現在只有1000條數據還好,數據量不大,如果是上千萬或者過億的話,那么消耗會非常大。
  2. 如果使用意向鎖的話,我們就不需要遍歷數據,我們發現Key上面有X鎖,那么會在表上面加一個IX鎖,而IX鎖與S鎖沖突,因此加S鎖失敗,這樣很快就得到了結果。

鎖兼容性控制多個事務能否同時獲取同一資源上的鎖。如果資源已被另一事務鎖定,則僅當請求鎖的模式與現有鎖的模式相兼容時,才會授予新的鎖請求。如果請求鎖的模式與現有鎖的模式不兼容,則請求新鎖的事務將被迫進入等待狀態,阻塞也就隨之產生。例如,如果一個事務申請了在某個資源上的排他鎖(X鎖),則在它釋放排他鎖(X鎖)之前,其他事務均無法獲取該資源的任何類型(共享、更新或排他)的鎖。另一種情況是,如果一個事務已經獲得了某個資源上的共享鎖(S鎖),則即使第一個事務尚未完成,其他事務也可以獲取該項的共享鎖或更新鎖(U鎖)。但是,在第一個事務釋放共享鎖之前,其他事務無法獲取排他鎖。

表9-3顯示了最常見的鎖模式的兼容性。

表9-3  最常見的鎖模式兼容性

 

現有授予模式

請求模式

IS

S

U

IX

SIX

X

意向共享(IS) [WX2] 

共享(S)

更新(U)

否 

意向排他(IX)

意向排他共享(SIX)

排他(X)

鎖的模式和兼容性是SQL Server預先定義好的,沒有任何參數或配置能夠去修改它們。但是可以通過隔離級別來控制申請鎖和釋放鎖的時機,四個隔離級別中申請與釋放S鎖時機可以參考:數據庫弱一致性四個隔離級別。但是申請鎖的粒度,是數據庫設計能夠影響的。如果應用申請的鎖粒度都比較小,產生阻塞的幾率就會比較小。如果一個連接會經常申請頁面級、表級,甚至是數據庫一級的鎖資源,程序產生阻塞的可能性就會很大。


免責聲明!

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



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