我遇到一个奇怪的死锁问题,其中2个select count(1)查询死锁。死锁XML如下:
<deadlock>
<victim-list>
<victimProcess id="process966db2ca8" />
</victim-list>
<process-list>
<process id="process966db2ca8" taskpriority="0" logused="444" waitresource="PAGE: 15:1:7396743 " waittime="1094" ownerId="3670863774" transactionname="implicit_transaction" lasttranstarted="2018-09-19T07:49:28.233" XDES="0x2cf8f8ad90" lockMode="S" schedulerid="13" kpid="15912" status="suspended" spid="822" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2018-09-19T07:49:28.247" lastbatchcompleted="2018-09-19T07:49:28.243" lastattention="1900-01-01T00:00:00.243" clientapp="Microsoft JDBC Driver for SQL Server" hostname="PGPHXSMEE001" hostpid="0" loginname="smee_user" isolationlevel="read committed (2)" xactid="3670863774" currentdb="15" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" stmtend="246" sqlhandle="0x02000000e44c632f5ec6f6a3183f3379f5c550436b652bdd0000000000000000000000000000000000000000">unknown</frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">unknown</frame>
</executionStack>
<inputbuf>(@P0 nvarchar(4000))select count(1) from SMEE_BookingManagement.dbo.booking_flagged_reason_mapping_t where gis_book_id = @P0</inputbuf>
</process>
<process id="process1fa2ebf468" taskpriority="0" logused="444" waitresource="PAGE: 15:1:1939674 " waittime="467" ownerId="3670873648" transactionname="implicit_transaction" lasttranstarted="2018-09-19T07:49:37.077" XDES="0xfca62c3b0" lockMode="S" schedulerid="6" kpid="11452" status="suspended" spid="808" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2018-09-19T07:49:37.093" lastbatchcompleted="2018-09-19T07:49:37.090" lastattention="1900-01-01T00:00:00.090" clientapp="Microsoft JDBC Driver for SQL Server" hostname="PGPHXSMEE001" hostpid="0" loginname="smee_user" isolationlevel="read committed (2)" xactid="3670873648" currentdb="15" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" stmtend="246" sqlhandle="0x02000000e44c632f5ec6f6a3183f3379f5c550436b652bdd0000000000000000000000000000000000000000">unknown</frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">unknown</frame>
</executionStack>
<inputbuf>(@P0 nvarchar(4000))select count(1) from SMEE_BookingManagement.dbo.booking_flagged_reason_mapping_t where gis_book_id = @P0</inputbuf>
</process>
</process-list>
<resource-list>
<pagelock fileid="1" pageid="7396743" dbid="15" subresource="FULL" objectname="SMEE_BookingManagement.dbo.BOOKING_FLAGGED_REASON_MAPPING_T" id="lock1c02483000" mode="IX" associatedObjectId="72057594057326592">
<owner-list>
<owner id="process1fa2ebf468" mode="IX" />
</owner-list>
<waiter-list>
<waiter id="process966db2ca8" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="1" pageid="1939674" dbid="15" subresource="FULL" objectname="SMEE_BookingManagement.dbo.BOOKING_FLAGGED_REASON_MAPPING_T" id="lock22f1a64f80" mode="SIX" associatedObjectId="72057594057326592">
<owner-list>
<owner id="process966db2ca8" mode="SIX" />
</owner-list>
<waiter-list>
<waiter id="process1fa2ebf468" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
</resource-list>
</deadlock>
表结构如下:
GIS_BOOK_ID_I仅是gis_book_id上的非聚簇索引。
要注意的一件事是,我在多线程环境中运行此选择查询,在该环境中某些线程可能会在运行此计数查询之前通过SID从该表中删除某些记录。这是请求IX和SIX锁的原因吗?如果是这样,有什么办法可以解决或减少这种僵局的发生率?谢谢。
更新:我问客户,他说我们可以放心地添加(NOLOCK)提示,因为当线程正在运行时,该表不太可能被其他进程更新。但是,请随时建议是否有更好的方法来处理此僵局。谢谢。