如果我正确地解密了以下死锁图,它看起来像两个进程(SPID:216和209)在同一页上拥有独占(X)锁:
XDL<资源列表>节目
<pagelock fileid="1" pageid="17410848" dbid="21" subresource="FULL" objectname="33bd93e0-f5b2-43f6-93ca-56bbe6493e0c.dbo.sync_publishers2" id="lock630b1d5380" mode="X" associatedObjectId="72057608416264192"> <owner-list> <owner id="process90763f08c8" mode="X" requestType="wait" /> </owner-list> <waiter-list> <waiter id="process861129bc28" mode="X" requestType="wait" /> </waiter-list> </pagelock>
还有一点点
<pagelock fileid="1" pageid="17410848" dbid="21" subresource="FULL" objectname="33bd93e0-f5b2-43f6-93ca-56bbe6493e0c.dbo.sync_publishers2" id="lock630b1d5380" mode="X" associatedObjectId="72057608416264192"> <owner-list> <owner id="process90763f04e8" mode="X" /> </owner-list> <waiter-list> <waiter id="process90763f08c8" mode="X" requestType="wait" /> </waiter-list> </pagelock>
怎么可能,这是什么意思?
完整的死锁定义如下:http://pastebin.com/A4Te3Chx.
UPD:我已经在Microsoft Connect上提交了一个项目来尝试收集权威回应:https://connect.microsoft.com/SQLServer/Feedback/Details/3119334.
解决方法
这只是意味着有一个等待该锁的队列.
您可以使用以下命令重新生成(运行setup,然后是tran 1.然后,您可以在15秒内按顺序在不同的连接中启动tran 2和tran 3).
建立
USE tempdb CREATE TABLE T ( X INT PRIMARY KEY WITH(ALLOW_ROW_LOCKS = OFF),Filler AS CAST('A' AS CHAR(8000)) PERSISTED ); INSERT INTO T VALUES (1),(2),(3);
特兰1
SET XACT_ABORT ON USE tempdb -- t1 BEGIN TRAN UPDATE T SET X = X WHERE X = 1 WAITFOR DELAY '00:00:15' --See what locks are granted just before the deadlock SELECT resource_description,request_status,request_session_id,X FROM sys.dm_tran_locks tl LEFT JOIN T WITH(NOLOCK) ON sys.fn_PhysLocFormatter(T.%% physloc%%) = '(' + RTRIM(resource_description) + ':0)' WHERE resource_associated_entity_id = (SELECT partition_id FROM sys.partitions WHERE object_id = object_id('T')); RAISERROR ('',1) WITH NOWAIT; UPDATE T SET X = X WHERE X = 3 WAITFOR DELAY '00:00:20' ROLLBACK
特兰2
SET XACT_ABORT ON USE tempdb -- t2 BEGIN TRAN UPDATE T SET X = X WHERE X = 2 UPDATE T SET X = X WHERE X = 1 WAITFOR DELAY '00:00:20' ROLLBACK
特兰3
SET XACT_ABORT ON USE tempdb -- t3 BEGIN TRAN UPDATE T SET X = X WHERE X = 3 UPDATE T SET X = X WHERE X = 1 ROLLBACK
在请求锁定之前立即对tran_locks进行查询的结果将会导致死锁
+----------------------+----------------+--------------------+---+ | resource_description | request_status | request_session_id | X | +----------------------+----------------+--------------------+---+ | 4:416 | GRANT | 61 | 1 | | 4:416 | WAIT | 64 | 1 | | 4:416 | WAIT | 65 | 1 | | 4:418 | GRANT | 64 | 2 | | 4:419 | GRANT | 65 | 3 | +----------------------+----------------+--------------------+---+
我收到的死锁图如下.
虽然它说死锁的受害者正在等待tran 2拥有的锁,但实际上并不是这样.在僵局的时候,锁由tran 1拥有,而tran 2在第3轮之前首先排在第一位.
死锁图XML显示了这一点,因为它具有相同资源的两个节点(第416页),而“所有者”中有一个requestType =“等待”
<resource-list> <pagelock fileid="4" pageid="416" dbid="2" subresource="FULL" objectname="tempdb.dbo.T" id="lock2486d8c4380" mode="X" associatedObjectId="936748728230805504"> <owner-list> <owner id="process2486ba0cca8" mode="X" requestType="wait" /> </owner-list> <waiter-list> <waiter id="process2485370c8c8" mode="X" requestType="wait" /> </waiter-list> </pagelock> <pagelock fileid="4" pageid="416" dbid="2" subresource="FULL" objectname="tempdb.dbo.T" id="lock2486d8c4380" mode="X" associatedObjectId="936748728230805504"> <owner-list> <owner id="process2485370c4e8" mode="X" /> </owner-list> <waiter-list> <waiter id="process2486ba0cca8" mode="X" requestType="wait" /> </waiter-list> </pagelock> <pagelock fileid="4" pageid="419" dbid="2" subresource="FULL" objectname="tempdb.dbo.T" id="lock248636ace80" mode="X" associatedObjectId="936748728230805504"> <owner-list> <owner id="process2485370c8c8" mode="X" /> </owner-list> <waiter-list> <waiter id="process2485370c4e8" mode="X" requestType="wait" /> </waiter-list> </pagelock> </resource-list>