Sql-Server
一個表上的更新語句在其他表上鎖定
鑑於 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);
解釋這些對像上的獨占鎖。