SQL Server 上不同行并发删除导致的死锁

问题描述 投票:0回答:1

我需要一些帮助来理解这种僵局场景。我们对表进行并发删除。这些操作在事务中删除一条记录并插入一条新记录(涉及其他表,但死锁图上没有报告锁定)。并发操作不针对相同的行。 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>  

sql-server deadlock database-deadlocks
1个回答
1
投票

仔细查看删除的执行计划后,我发现可能导致问题的原因。该表有一个针对同一表上另一列的外键(它是一个分层实体)。从死锁图可以看出,死锁发生在主键上,但实际上是由于这个FK造成的。删除 FK 并控制应用程序上的引用完整性解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.