Sql-Server-2016

為什麼在層次結構中的更高級別使用意圖鎖,為什麼不使用正常鎖?

  • December 1, 2020

本文建議在鎖層次結構的較高級別使用意圖鎖,以指示已在較低級別上獲取鎖。這種機制的想法是,如果 SQL Server 想要在頁面或表上放置鎖,則不需要檢查每一行是否有活動鎖。

例如,如果我更新 AdventureWorks 中的一行:

USE AdventureWorks2014;

BEGIN TRAN;
UPDATE  Person.Person 
SET     LastName = 'Smith' 
WHERE   BusinessEntityID = 1;

然後在另一個會話中,執行sp_whoisactivewithget_locks以查看使用了哪些鎖:

EXEC sp_whoisactive @get_locks = 1;

我可以看到以下內容:

     <Locks>
       <Lock resource_type="KEY" index_name="IX_Person_LastName_FirstName_MiddleName" request_mode="X" request_status="GRANT" request_count="2" />
       <Lock resource_type="KEY" index_name="PK_Person_BusinessEntityID" request_mode="X" request_status="GRANT" request_count="1" />
       <Lock resource_type="OBJECT" request_mode="IX" request_status="GRANT" request_count="1" />
       <Lock resource_type="PAGE" page_type="*" index_name="IX_Person_LastName_FirstName_MiddleName" request_mode="IX" request_status="GRANT" request_count="4" />
       <Lock resource_type="PAGE" page_type="*" index_name="PK_Person_BusinessEntityID" request_mode="IX" request_status="GRANT" request_count="1" />
     </Locks>

這支持了上面的文章所說的——我們在兩個相關索引上有一個排他的行(鍵)鎖,因此頁面和對像有 IX 鎖。

如果我嘗試在另一個會話中選擇該行:

SELECT * FROM Person.Person WHERE BusinessEntityID = 1

該查詢確實被阻止了。

因此,我的問題是,為什麼意圖鎖與“正常”鎖不同?為什麼 SQL Server 不只是在表上放置 X 鎖?

我已經找到了答案(如果我的理解有誤,請更正)

經過多讀後,我在這裡找到了一個簡單的矩陣:

在此處輸入圖像描述

與 IX 鎖相比,X 鎖與其他鎖的兼容性似乎較差。

如果我們因為讀取一行而在表上放置 X 鎖,我們無法在該表上獲得 IS 鎖,但如果我們在表上有 IX 鎖,我們可以獲得 IS 鎖。

如果我理解正確的話,如果我們用 X 鎖鎖定表來更新一行,我們就不能讀取不同的行,因為讀取不能在表上放置 IS。但是,如果我們使用 IX,它可以獲得所需的 IS 鎖。

以下測試似乎證明了這種情況:

更新單行:

USE AdventureWorks2016;

BEGIN TRAN;
UPDATE  Person.Person 
SET     LastName = 'Smith' 
WHERE   BusinessEntityID = 1;

在另一個會話中,選擇與正在更新的行不同的行

SELECT * FROM Person.Person WHERE BusinessEntityID = 2

此行返回而不被阻塞

但是,如果我要獲得 X 鎖:

USE AdventureWorks2016;

BEGIN TRAN;
UPDATE  Person.Person WITH (TABLOCKX)
SET     LastName = 'Smith' 
WHERE   BusinessEntityID = 1;

此查詢現在被阻止:

SELECT * FROM Person.Person WHERE BusinessEntityID = 2

引用自:https://dba.stackexchange.com/questions/280627