Sql-Server

一個表上的更新語句在其他表上鎖定

  • September 11, 2019

鑑於 AdventureWorks 數據庫的以下語句:

UPDATE Sales.SalesOrderDetail SET OrderQty = 100 WHERE ModifiedDate >= '2014-01-01'

如果我打開另一個查詢視窗並通過執行查看查詢正在使用的鎖

sp_WhoIsActive @get_locks =1

我可以看到鎖如下:

  <Object name="Person" schema_name="Person">
     <Locks>
       <Lock resource_type="OBJECT" request_mode="X" request_status="GRANT" request_count="1" />
     </Locks>
   </Object>
   <Object name="SalesOrderDetail" schema_name="Sales">
     <Locks>
       <Lock resource_type="OBJECT" request_mode="X" request_status="GRANT" request_count="1" />
     </Locks>
   </Object>
   <Object name="SalesOrderHeader" schema_name="Sales">
     <Locks>
       <Lock resource_type="OBJECT" request_mode="X" request_status="GRANT" request_count="1" />
     </Locks>
   </Object>

我期待 SalesOrderDetail 上的表鎖但是,我不明白為什麼在 Person 表和 SalesOrderHeader 表上使用了表鎖

SELECT *我可以通過嘗試從隨後被阻止的一張表中確認鎖存在。

為什麼更新語句會鎖定未更新的表?

由於觸發器,表被鎖定:[iduSalesOrderDetail]on[Sales].[SalesOrderDetail]

在此處輸入圖像描述

如果發生以下任何操作,觸發器就會啟動:

IF UPDATE([ProductID]) OR UPDATE([OrderQty]) OR UPDATE([UnitPrice]) OR UPDATE([UnitPriceDiscount])

並且UPDATE([OrderQty])是這些行動之一。

然後此觸發器將更新Person.Person兩次。

這些Update陳述之一:

 UPDATE [Person].[Person] 
           SET [Demographics].modify('declare default element namespace 
               "http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey"; 
               replace value of (/IndividualSurvey/TotalPurchaseYTD)[1] 
               with data(/IndividualSurvey/TotalPurchaseYTD)[1] + sql:column ("inserted.LineTotal")') 
           FROM inserted 
               INNER JOIN [Sales].[SalesOrderHeader] AS SOH
               ON inserted.[SalesOrderID] = SOH.[SalesOrderID] 
               INNER JOIN [Sales].[Customer] AS C
               ON SOH.[CustomerID] = C.[CustomerID]
           WHERE C.[PersonID] = [Person].[Person].[BusinessEntityID];

並且Sales.SalesOrderHeader

UPDATE [Sales].[SalesOrderHeader]
       SET [Sales].[SalesOrderHeader].[SubTotal] = 
           (SELECT SUM([Sales].[SalesOrderDetail].[LineTotal])
               FROM [Sales].[SalesOrderDetail]
               WHERE [Sales].[SalesOrderHeader].[SalesOrderID] = [Sales].[SalesOrderDetail].[SalesOrderID])
       WHERE [Sales].[SalesOrderHeader].[SalesOrderID] IN (SELECT inserted.[SalesOrderID] FROM inserted);

解釋這些對像上的獨占鎖。

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