Pau*_*ams 5 sql-server-2005 sql-server deadlock
我们的一位客户经常遇到僵局。死锁大多在同一个UPDATE语句上。死锁遵循一种模式,其中两个 SPID 都已获取页上的更新 (U) 锁,并且都尝试将 U 页锁向上转换为意图排他 (IX) 锁。有时只涉及一页;有时几个。
我们使用跟踪标志 1222捕获了死锁跟踪。SQL Server 日志显示了许多具有以下模式的死锁(按自下而上的顺序):
waiter id=processe0dc2088 mode=U requestType=convert
waiter id=process2f9db2478 mode=U requestType=convert
waiter-list
owner id=processe0dc2088 mode=IX
owner id=process2f9db2478 mode=IX
owner-list
pagelock fileid=1 pageid=5794 dbid=2 objectname=tempdb.dbo.Item_Package_Site_Costs_Work id=lock1b22de480 mode=IX associatedObjectId=72057594131775488
resource-list
Run Code Online (Sandbox Code Playgroud)
两个进程都运行相同的 UPDATE 语句来在这个 tempdb 表上设置一个标志。此 tempdb 表包含需要在客户端调用之间保留的信息,直到客户端完成。该表有一个相当长的索引,以代表唯一进程 ID 的 GUID 开头。
我很难理解和模拟这种僵局。我用模拟数据尝试了各种数量的记录。
我的问题:
为什么这些进程获取U锁然后转换为IX? 我希望 DELETE 开始获取 IX 锁。
我怎样才能防止死锁?
导致死锁的语句如下。该流程刚刚完成了对单个商店中商品清单的成本查询。它试图指出发现了一个成本。
请注意,UPDATE 语句中有一个已弃用的 (NOLOCK)。这会是一个促成因素吗?
UPDATE tempdb..Item_Package_Site_Costs_Work
SET ItemPkgSiteCost_VINCostFound = 1,
ItemPkgSiteCost_VendCost_Key = SiteCosts_VendCost_Key
FROM tempdb..Item_Package_Site_Costs_Work (NOLOCK)
INNER JOIN #SiteCosts
ON ItemPkgSiteCost_GUID = @ProcGUID
AND SiteCosts_Item_Type = 0 -- Standard
AND ItemPkgSiteCost_Site_Key = SiteCosts_Input_Site_Key
AND ItemPkgSiteCost_Item_Key = SiteCosts_Item_Key
AND ItemPkgSiteCost_ItemPkg_Key = SiteCosts_Input_Sel_ItemPkg_Key
AND ItemPkgSiteCost_VendItem_Key = SiteCosts_VendItem_Key
AND ISNULL(ItemPkgSiteCost_Qty_Recv, 1) = SiteCosts_Input_Qty_Recv
Run Code Online (Sandbox Code Playgroud)
客户的服务器@@version是:
Microsoft SQL Server 2005 - 9.00.4035.00 (X64) 2008 年 11 月 24 日 16:17:31 版权所有 (c) 1988-2005 Windows NT 6.1(内部版本 7601:Service Pack 1)上的 Microsoft Corporation 标准版(64 位)
到目前为止,我还无法捕获死锁时使用的查询计划,并且我尝试检索查询计划的正常方法没有返回任何内容(sys.dm_exec_query_plan和sys.dm_exec_text_query_plan都返回 NULL)。
更新 2013-08-29
客户安装了 SQL Server 2005 SP 4,但他们仍然看到这个死锁。我将继续删除正在修改的表上不推荐使用的 (NOLOCK),看看这是否可以解决死锁。
首先,进程持有 IX 并希望转换为 U。这是查询中的提示所预期的。
两个查询都将在选择期间使用 IX 锁,然后在需要发生更改(如果有)时转换为 U。
这可以通过添加: WITH (XLOCK) 作为临时表的提示来解决。
| 归档时间: |
|
| 查看次数: |
6130 次 |
| 最近记录: |