我需要一些帮助来理解这种僵局场景。我们对表进行并发删除。这些操作在事务中删除一条记录并插入一条新记录(涉及其他表,但死锁图上没有报告锁定)。并发操作不针对相同的行。 xml 也不显示页面锁定。我不明白为什么会发生僵局。使用已提交读或已提交读快照隔离级别都会发生这种情况。
这是死锁图和xml:
xml_report
<deadlock>
<victim-list>
<victimProcess id="process111c0a04e8"/>
</victim-list>
<process-list>
<process id="process111c0a04e8" taskpriority="0" logused="988" waitresource="KEY: 5:72057594052476928 (cdccc9664fb5)" waittime="572" ownerId="402767" transactionname="implicit_transaction" lasttranstarted="2023-08-09T15:56:06.700" XDES="0x113940c428" lockMode="S" schedulerid="6" kpid="32656" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2023-08-09T15:56:06.753" lastbatchcompleted="2023-08-09T15:56:06.743" lastattention="1900-01-01T00:00:00.743" clientapp="Microsoft JDBC Driver for SQL Server" hostname="W3737985" hostpid="0" loginname="sa" isolationlevel="snapshot (5)" xactid="402767" currentdb="5" currentdbname="bcecm" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" stmtend="112" sqlhandle="0x02000000f1caf30cb9946dc3186f8369fd94f3a26b002a540000000000000000000000000000000000000000"> unknown </frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"> unknown </frame>
</executionStack>
<inputbuf> (@P0 nvarchar(4000))delete from Documento WHERE id = @P0 </inputbuf>
</process>
<process id="processb8de6eca8" taskpriority="0" logused="988" waitresource="KEY: 5:72057594052476928 (cdccc9664fb5)" waittime="572" ownerId="402796" transactionname="implicit_transaction" lasttranstarted="2023-08-09T15:56:06.767" XDES="0x113430c428" lockMode="S" schedulerid="9" kpid="36848" status="suspended" spid="68" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2023-08-09T15:56:06.823" lastbatchcompleted="2023-08-09T15:56:06.813" lastattention="1900-01-01T00:00:00.813" clientapp="Microsoft JDBC Driver for SQL Server" hostname="W3737985" hostpid="0" loginname="sa" isolationlevel="snapshot (5)" xactid="402796" currentdb="5" currentdbname="bcecm" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" stmtend="112" sqlhandle="0x02000000f1caf30cb9946dc3186f8369fd94f3a26b002a540000000000000000000000000000000000000000"> unknown </frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"> unknown </frame>
</executionStack>
<inputbuf> (@P0 nvarchar(4000))delete from Documento WHERE id = @P0 </inputbuf>
</process>
<process id="process1117804108" taskpriority="0" logused="988" waitresource="KEY: 5:72057594052476928 (1af84d4c4a2b)" waittime="99" ownerId="402813" transactionname="implicit_transaction" lasttranstarted="2023-08-09T15:56:06.780" XDES="0x1142190428" lockMode="S" schedulerid="1" kpid="34780" status="suspended" spid="72" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2023-08-09T15:56:06.830" lastbatchcompleted="2023-08-09T15:56:06.823" lastattention="1900-01-01T00:00:00.823" clientapp="Microsoft JDBC Driver for SQL Server" hostname="W3737985" hostpid="0" loginname="sa" isolationlevel="snapshot (5)" xactid="402813" currentdb="5" currentdbname="bcecm" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" stmtend="112" sqlhandle="0x02000000f1caf30cb9946dc3186f8369fd94f3a26b002a540000000000000000000000000000000000000000"> unknown </frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"> unknown </frame>
</executionStack>
<inputbuf> (@P0 nvarchar(4000))delete from Documento WHERE id = @P0 </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594052476928" dbid="5" objectname="bcecm.dbo.documento" indexname="PK__document__3213E83FFA04E697" id="lock113213f500" mode="X" associatedObjectId="72057594052476928">
<owner-list>
<owner id="processb8de6eca8" mode="S" requestType="wait"/>
</owner-list>
<waiter-list>
<waiter id="process111c0a04e8" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594052476928" dbid="5" objectname="bcecm.dbo.documento" indexname="PK__document__3213E83FFA04E697" id="lock113213f500" mode="X" associatedObjectId="72057594052476928">
<owner-list>
<owner id="process1117804108" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="processb8de6eca8" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594052476928" dbid="5" objectname="bcecm.dbo.documento" indexname="PK__document__3213E83FFA04E697" id="lock112348fb80" mode="X" associatedObjectId="72057594052476928">
<owner-list>
<owner id="process111c0a04e8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process1117804108" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
仔细查看删除的执行计划后,我发现可能导致问题的原因。该表有一个针对同一表上另一列的外键(它是一个分层实体)。从死锁图可以看出,死锁发生在主键上,但实际上是由于这个FK造成的。删除 FK 并控制应用程序上的引用完整性解决了问题。