I'm helping troubleshoot some deadlocking in a .NET application that uses SQL Server 2005. I have the XML data from the trace below.
What really puzzles me is the RangeX-X lock on PK_Exp_Experience_PriorFirm
when the transaction isolation level is read committed.
Everything I've read indicates that you only get a key-range lock of you are using the transaction isolation level "serializable". So far, I can't find any places in our application where we set the isolation level to anything other than read committed, and the XML below also indicates that we're using read committed.
But if we're using read-committed, I don't understand how the trace shows there being a key-range lock. Does anyone have ideas about how that could be happening?
<deadlock-list>
<deadlock victim="processc2f438">
<process-list>
<process id="processc2f438" taskpriority="0" logused="13488" waitresource="KEY: 120:72057594583646208 (8201498b6efe)" waittime="484" ownerId="693258089" transactionname="user_transaction" lasttranstarted="2009-01-06T16:33:27.817" XDES="0xa71ce370" lockMode="U" schedulerid="1" kpid="9112" status="suspended" spid="53" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2009-01-06T16:33:27.863" lastbatchcompleted="2009-01-06T16:33:27.863" clientapp=".Net SqlClient Data Provider" hostname="CHQAPT3" hostpid="6464" loginname="AppUser" isolationlevel="read committed (2)" xactid="693258089" currentdb="120" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="108" sqlhandle="0x0200000015d9962978fc6206b09e4c872150511b455e8923">
UPDATE Exp_Experience_PriorFirm SET RelatedGuid = @newGuid WHERE RelatedGuid = @oldGuid
</frame>
<frame procname="mssqlsystemresource.sys.sp_executesql" line="1" sqlhandle="0x0400ff7fbe80662601000000000000000000000000000000">
sp_executesql
</frame>
<frame procname="MyDb.dbo.Contact_MergeRelationships" line="74" stmtstart="4754" stmtend="4976" sqlhandle="0x0300780036a608461ed8af00669b00000100000000000000">
EXEC sp_executesql @sql,
N'@oldGuid uniqueidentifier, @newGuid uniqueidentifier',
@oldGuid, @newGuid
</frame>
<frame procname="MyDb.dbo.Contact_Company_MergeRelationships" line="8" stmtstart="312" sqlhandle="0x03007800b271a129c8ccaf00669b00000100000000000000">
EXEC Contact_MergeRelationships @oldGuid, @newGuid, 'Contact_Company', @excludedTableNames
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 120 Object Id = 698446258]
</inputbuf>
</process>
<process id="processeb5d68" taskpriority="0" logused="14212" waitresource="KEY: 120:72057594594066432 (7c02a3a5890e)" waittime="2312" ownerId="693243114" transactionname="user_transaction" lasttranstarted="2009-01-06T16:33:20.957" XDES="0x8cdb9450" lockMode="S" schedulerid="2" kpid="9000" status="suspended" spid="73" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2009-01-06T16:33:29.770" lastbatchcompleted="2009-01-06T16:33:29.770" clientapp=".Net SqlClient Data Provider" hostname="CHQAPT3" hostpid="6464" loginname="AppUser" isolationlevel="read committed (2)" xactid="693243114" currentdb="120" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="MyDb.dbo.Contact_Company_Delete" line="27" stmtstart="1128" sqlhandle="0x03007800b0e5761877cbaf00669b00000100000000000000">
DELETE FROM Contact WHERE GUID = @Guid;
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 120 Object Id = 410445232]
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594583646208" dbid="120" objectname="MyDb.dbo.Exp_Experience_PriorFirm" indexname="PK_Exp_Experience_PriorFirm" id="lockd1d43f80" mode="RangeX-X" associatedObjectId="72057594583646208">
<owner-list>
<owner id="processeb5d68" mode="RangeX-X"/>
</owner-list>
<waiter-list>
<waiter id="processc2f438" mode="U" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594594066432" dbid="120" objectname="MyDb.dbo.Contact_PersonCompanyLocation" indexname="PK_Contact_PersonCompanyLocation" id="lockd20c4380" mode="X" associatedObjectId="72057594594066432">
<owner-list>
<owner id="processc2f438" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="processeb5d68" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>