删除查询阻塞其他并发事务

use*_*827 0 sql-server deadlock delete locking sql-server-2016

DELETE我的生产 SQL 服务器中的查询导致死锁。我知道 DELETE 导致了这种情况,因为我检查了扩展事件并检查了死锁 XML 并发现此 DELETE 正在阻塞,这最终导致死锁。

所以DELETE是发生在两个表格,TB1和TB2。tb1 的主键在 tb2 中可用作外键,并CASCADE DELETE在 tb2 外键中使用。

我什Allow Page LocksFALSE在 tb1 和 tb2 中创建了聚集索引,但仍然没有运气。

我想READ COMMITTED SNAPSHOT在我的数据库中尝试之前尝试所有其他选项。

任何帮助将不胜感激。

附加信息:

使用READ COMMITTED SNAPSHOT也是一个挑战,因为它涉及风险。

  • 我的数据库大小很大(~1.6 TB),RAM 为 128 GB。
  • 使用 SQL Server 2016

这是 XDL

<deadlock>
 <victim-list>
  <victimProcess id="process257a65d6ca8" />
 </victim-list>
 <process-list>
  <process id="process257a65d6ca8" taskpriority="0" logused="6024" waitresource="KEY: 6:72057794784329728 (bb7a6e52eae1)" waittime="4485" ownerId="45816472292" transactionname="user_transaction" lasttranstarted="2019-01-08T11:30:06.837" XDES="0x24883ec2a70" lockMode="RangeS-U" schedulerid="26" kpid="39320" status="suspended" spid="217" sbid="2" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-01-08T11:30:06.883" lastbatchcompleted="2019-01-08T11:30:06.870" lastattention="1900-01-01T00:00:00.870" clientapp="iyeTek.Services.MSP.AICS.Host.MSP" hostname="EAICS-APP-01" hostpid="5356" loginname="pasl_msp" isolationlevel="read committed (2)" xactid="45816472292" currentdb="6" currentdbname="iyeTek.Services.MSP.AICS" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="1" stmtstart="42" stmtend="116" sqlhandle="0x0200000032f3ca31d40d7b71d6e79a1044a3a86617a5be1e0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@0 uniqueidentifier)DELETE [dbo].[Form]
WHERE ([Id] = @0)   </inputbuf>
  </process>
  <process id="process252a472e8c8" taskpriority="0" logused="7552" waitresource="KEY: 6:72057794784329728 (1a150171029d)" waittime="706" ownerId="45816472158" transactionname="user_transaction" lasttranstarted="2019-01-08T11:30:06.733" XDES="0x23eb032a430" lockMode="RangeS-U" schedulerid="30" kpid="66604" status="suspended" spid="283" sbid="2" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-01-08T11:30:06.827" lastbatchcompleted="2019-01-08T11:30:06.803" lastattention="1900-01-01T00:00:00.803" clientapp="iyeTek.Services.MSP.AICS.Host.MSP" hostname="EAICS-APP-03" hostpid="6216" loginname="pasl_msp" isolationlevel="read committed (2)" xactid="45816472158" currentdb="6" currentdbname="iyeTek.Services.MSP.AICS" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="1" stmtstart="42" stmtend="116" sqlhandle="0x0200000032f3ca31d40d7b71d6e79a1044a3a86617a5be1e0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@0 uniqueidentifier)DELETE [dbo].[Form]
WHERE ([Id] = @0)   </inputbuf>
  </process>
  <process id="process245373d2ca8" taskpriority="0" logused="77556" waitresource="KEY: 6:72057794784329728 (bb7a6e52eae1)" waittime="3216" ownerId="45816432209" transactionname="user_transaction" lasttranstarted="2019-01-08T11:30:00.563" XDES="0x255954753d0" lockMode="RangeS-U" schedulerid="33" kpid="19100" status="suspended" spid="381" sbid="2" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-01-08T11:30:08.130" lastbatchcompleted="2019-01-08T11:30:08.120" lastattention="1900-01-01T00:00:00.120" clientapp="iyeTek.Services.MSP.AICS.Host.MSP" hostname="EAICS-APP-03" hostpid="6216" loginname="pasl_msp" isolationlevel="read committed (2)" xactid="45816432209" currentdb="6" currentdbname="iyeTek.Services.MSP.AICS" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="1" stmtstart="42" stmtend="116" sqlhandle="0x0200000032f3ca31d40d7b71d6e79a1044a3a86617a5be1e0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@0 uniqueidentifier)DELETE [dbo].[Form]
WHERE ([Id] = @0)   </inputbuf>
  </process>
 </process-list>
 <resource-list>
  <keylock hobtid="72057794784329728" dbid="6" objectname="iyeTek.Services.MSP.AICS.dbo.FormNarrative" indexname="PK_FormNarrative" id="lock24c95634480" mode="RangeS-U" associatedObjectId="72057794784329728">
   <owner-list>
    <owner id="process252a472e8c8" mode="RangeS-U" />
   </owner-list>
   <waiter-list>
    <waiter id="process257a65d6ca8" mode="RangeS-U" requestType="wait" />
   </waiter-list>
  </keylock>
  <keylock hobtid="72057794784329728" dbid="6" objectname="iyeTek.Services.MSP.AICS.dbo.FormNarrative" indexname="PK_FormNarrative" id="lock251d3ea0c00" mode="RangeX-X" associatedObjectId="72057794784329728">
   <owner-list>
    <owner id="process245373d2ca8" mode="RangeX-X" />
   </owner-list>
   <waiter-list>
    <waiter id="process252a472e8c8" mode="RangeS-U" requestType="wait" />
   </waiter-list>
  </keylock>
  <keylock hobtid="72057794784329728" dbid="6" objectname="iyeTek.Services.MSP.AICS.dbo.FormNarrative" indexname="PK_FormNarrative" id="lock24c95634480" mode="RangeS-U" associatedObjectId="72057794784329728">
   <owner-list>
    <owner id="process257a65d6ca8" mode="RangeS-U" requestType="wait" />
   </owner-list>
   <waiter-list>
    <waiter id="process245373d2ca8" mode="RangeS-U" requestType="wait" />
   </waiter-list>
  </keylock>
 </resource-list>
</deadlock>
Run Code Online (Sandbox Code Playgroud)

Bre*_*zar 5

如果您使用级联删除,那么是的,它们会自动升级为可序列化的锁,如死锁图的 lockMode="RangeS-U" 部分所示,这几乎阻止了子表上的其他所有人。更改读提交的快照不会改变任何东西。

您需要更改代码以先对子表进行删除,然后再对父表进行删除,而不是依赖级联删除。在桌面上运行良好但在规模上分崩离析的那些很好的例子之一。