May 31, 2012 at 1:06 pm
The server I am working with is SQL Server 2005 v9.0.4262 Enterprise x64
I have a deadlock issue between two stored procedures. Both are doing an UPDATE statement to the same table at the time of the deadlock. The table is clustered on an ID field. All SELECT statements in the procedures against that table are using the NOLOCk locking hint.
The issue I am seeing is that procedure A has a mode=U lock on a key and proc B is waiting on a mode=X lock, meanwhile proc B has a mode=U lock on the same key and proc A is waiting on a mode=X lock.
Based on what I've read, this scenario should be impossible because you can't have an update lock and an exclusive lock on the same resource. Does this look like some kind of bug in SQL Server for this version I am running or am I misunderstanding something with how locking works?
Any help is appreciated. Below is the locking table and the deadlock trace.
Lock Chart
Deadlock output
Deadlock encountered .... Printing deadlock information
Wait-for graph
Node:1
KEY: 6:72057594515554304 (f500c4ba8e6b) CleanCnt:2 Mode:U Flags: 0x0
Grant List 1:
Owner:0x0000000004520280 Mode: U Flg:0x0 Ref:0 Life:00000001 SPID:72 ECID:0 XactLockInfo: 0x0000000274655758
SPID: 72 ECID: 0 Statement Type: UPDATE Line #: 134
Input Buf: RPC Event: Proc [Database Id = 6 Object Id = 1918994263]
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x00000000A6A506C0 Mode: U SPID:59 BatchID:0 ECID:0 TaskProxy:(0x000000037C0F2598) Value:0x55bff80 Cost:(0/0)
Node:2
KEY: 6:72057594515554304 (91008ead68c0) CleanCnt:3 Mode:X Flags: 0x0
Grant List 0:
Owner:0x00000000049916C0 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:61 ECID:0 XactLockInfo: 0x00000002D6E0C3A8
SPID: 61 ECID: 0 Statement Type: UPDATE Line #: 59
Input Buf: RPC Event: Proc [Database Id = 6 Object Id = 1166991584]
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x0000000274655720 Mode: U SPID:72 BatchID:0 ECID:0 TaskProxy:(0x00000001BB8AC598) Value:0xed128900 Cost:(0/220)
Node:3
KEY: 6:72057594515554304 (2d0053c43b84) CleanCnt:2 Mode:U Flags: 0x0
Grant List 1:
Owner:0x0000000004520F40 Mode: U Flg:0x0 Ref:0 Life:00000001 SPID:72 ECID:0 XactLockInfo: 0x0000000274655758
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x00000002D6E0C370 Mode: X SPID:61 BatchID:0 ECID:0 TaskProxy:(0x000000016EE0E598) Value:0x4d9b080 Cost:(0/468)
Victim Resource Owner:
ResType:LockOwner Stype:'OR'Xdes:0x0000000274655720 Mode: U SPID:72 BatchID:0 ECID:0 TaskProxy:(0x00000001BB8AC598) Value:0xed128900 Cost:(0/220)
deadlock-list
deadlock victim=process3827048
process-list
process id=process38129b8 taskpriority=0 logused=468 waitresource=KEY: 6:72057594515554304 (2d0053c43b84) waittime=4578 ownerId=12298661353 transactionname=user_transaction lasttranstarted=2012-05-31T11:27:51.970 XDES=0x2d6e0c370 lockMode=X schedulerid=2 kpid=2696 status=suspended spid=61 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2012-05-31T11:27:51.970 lastbatchcompleted=2012-05-31T11:27:51.970 clientapp=.Net SqlClient Data Provider hostname=MyWebServer hostpid=7448 loginname=MyLoginName isolationlevel=read committed (2) xactid=12298661353 currentdb=6 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=MyDB.dbo.ProcA line=59 stmtstart=3220 stmtend=3444 sqlhandle=0x03000600e0e08e450cf824016d9a00000100000000000000
UPDATE dbo.MyTable
SET JobsRemaining = JobsRemaining - @Transactions
WHERE MyTable.ID = @NewFounderID;
inputbuf
Proc [Database Id = 6 Object Id = 1166991584]
process id=process3827048 taskpriority=0 logused=220 waitresource=KEY: 6:72057594515554304 (91008ead68c0) waittime=4718 ownerId=12298661341 transactionname=user_transaction lasttranstarted=2012-05-31T11:27:51.960 XDES=0x274655720 lockMode=U schedulerid=4 kpid=5452 status=suspended spid=72 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2012-05-31T11:27:51.960 lastbatchcompleted=2012-05-31T11:27:51.960 clientapp=.Net SqlClient Data Provider hostname=MyWebServer hostpid=5400 loginname=MyLoginName isolationlevel=read committed (2) xactid=12298661341 currentdb=6 lockTimeout=4294967295 clientoption1=673185824 clientoption2=128056
executionStack
frame procname=MyDB.dbo.ProcB line=134 stmtstart=14710 stmtend=16208 sqlhandle=0x0300060057876172541c9500739e00000100000000000000
UPDATE dbo.MyTable
SET JobsRemaining = JobsRemaining - 1
FROM
dbo.MyTableB WITH (NOLOCK)
JOIN dbo.MyTableC WITH (NOLOCK) ON MyTableC.UserID = MyTableB.UserID
WHERE
MyTableB.JdtID = @JdtID
and MyTable.ID = COALESCE((SELECT TOP 1 AncestorID
FROM dbo.MyTableD WITH (NOLOCK)
WHERE GroupID = MyTableC.GroupID
ORDER BY Generation DESC), MyTableC.GroupID);
inputbuf
Proc [Database Id = 6 Object Id = 1918994263]
resource-list
keylock hobtid=72057594515554304 dbid=6 objectname=MyDB.dbo.MyTable indexname=PK_MyTable id=lock3919280 mode=X associatedObjectId=72057594515554304
owner-list
owner id=process38129b8 mode=X
waiter-list
waiter id=process3827048 mode=U requestType=wait
keylock hobtid=72057594515554304 dbid=6 objectname=MyDB.dbo.MyTable indexname=PK_MyTable id=lock43be180 mode=U associatedObjectId=72057594515554304
owner-list
owner id=process3827048 mode=U
waiter-list
waiter id=process38129b8 mode=X requestType=wait
May 31, 2012 at 1:11 pm
Would also help if you would post the code involved.
June 1, 2012 at 7:58 am
I don't think I'm allowed to post the code.
I really just want to know if this locking scenario is something that should be unexpected. Based on everything I've read online, having two spids with an update and an exclusive lock on the same resource should be impossible. I want to know if there are any known scenarios that could cause this situation and what the resolution to those scenarios are.
The only statements that are touching the table involved in the deadlock are a couple of SELECT statements using NOLOCK and then one update statement in one proc and 3 update statements in the other proc. The code for the exact statements that are deadlocking are in the deadlock output with the sensitive names replaced.
June 1, 2012 at 9:09 am
Here is the problem, we can't see from here what you see. You are basically asking us to shoot in the dark and hope we hit the mark. You have to help us help you. If you can't post the actual code for the procedures then you you need to mock up something that properly represents your code but isn't.
If two update procedures are deadlocking each other there is a very good chance that it is code related. Without looking at it, there is no way for us to even know. I'm sorry, but the force only helps so much.
June 1, 2012 at 10:41 am
I understand. I will see if I can get a mocked up version of the code that accurately represents what's actually going on.
thank you
Viewing 5 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic. Login to reply