Sql-Server

帶有“insert into”語句的觸發器是否會導緻小型插入操作的 Intext Exclusive 鎖?

  • August 26, 2020

我們有一個觸發器,它在一個表(節點)中的插入之後執行,它在另一個表(NodeClosures)中創建條目,從 NodeClosures 表中選擇條目(平均 6 個)並將它們作為具有不同值的新行插入到某個列中. Nodes 表中的插入操作一次發生一個(因此沒有單個大批量插入操作,實體框架),並且對 NodeClosures 表的選擇/插入操作會導致意圖排他鎖。我不確定這是否是由於鎖升級(不確定插入操作如何插入超過 6 行)。一些附加資訊,正在使用已送出的讀取快照隔離以及延遲的持久性事務。

我已包含完整的觸發器以供參考(MSSQL 2017):

CREATE TRIGGER [tr_dbNode_insert]
ON [dbo].[DbNodes]
After INSERT
AS
BEGIN
   -- Insert self closure
   insert into DbNodeClosures (ParentID, ChildID, Depth, AccountID)
   select Id, Id, 0, AccountID
   from inserted;
   -- Insert parent's closures as it's own + 1
   insert into DbNodeClosures (ParentID, ChildID, Depth, AccountID)
   select closures.ParentID, inserted.Id, closures.Depth + 1, inserted.AccountID
   from inserted join DbNodeClosures as closures on inserted.ParentID = closures.ChildID;

END

對您的問題的簡短回答是 - 是的,任何插入,即使是單行,都可能導致 Intent-Exclusive 鎖,但在鎖層次結構中的級別高於所採用的實際獨占鎖。

Intent-Exclusive 鎖表示請求已在 Lock Hierarchy ( Database (High) -> Table -> Page -> Row (Low)) 中的較低級別獲取了獨占鎖。例如,如果您在表級別看到 IX 鎖,則表明請求在頁或行級別具有 X 鎖。如果您在頁級別看到 IX 鎖,則在行級別存在 X 鎖。請注意,在鎖升級中,Row 不會升級到 Page,而是 Row 和 Page 鎖都會升級到 Table 鎖。

Intent Exclusive lock 本身並不表示鎖升級,它用於控制更高級別資源的鎖,以確保尊重所有事務的隔離級別。如果您的觸發器正在更新 6 行,那麼它很可能只有行或頁面級別的獨占鎖,並且表級別將顯示意圖獨占鎖。這會影響其他會話通過指示較低級別的資源已被鎖定來嘗試鎖定較高級別的資源。

查看這篇文章以獲得對不同鎖及其相互兼容性的良好解釋。

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