我正在帮助解决使用 SQL Server 2005 的 .NET 应用程序中的一些死锁问题。我有来自下面跟踪的 XML 数据。
PK_Exp_Experience_PriorFirm
真正让我困惑的是当事务隔离级别被读取提交时RangeX-X 锁定。
我读过的所有内容都表明您使用事务隔离级别“可序列化”只会获得一个键范围锁。到目前为止,我在我们的应用程序中找不到将隔离级别设置为读取提交以外的任何位置,并且下面的 XML 也表明我们正在使用读取提交。
但是,如果我们使用已提交读,我不明白跟踪如何显示存在键范围锁。有没有人知道如何发生这种情况?
<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>