Дедлок с повторной блокировкой ресурса (ms sql 2014)
Столкнулся со следующим дедлоком:
<deadlock-list>
<deadlock victim="process233c64ffc28">
<process-list>
<process id="process233c64ffc28" taskpriority="0" logused="0" waitresource="KEY: 39:72057594166247424 (c0af60d834ba)" waittime="23" ownerId="775457003509" transactionname="MERGE" lasttranstarted="2021-08-05T16:10:03.740" XDES="0x1d12ad5ed10" lockMode="U" schedulerid="25" kpid="181500" status="suspended" spid="4722" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-08-05T16:10:00.877" lastbatchcompleted="2021-08-05T16:10:00.877" lastattention="1900-01-01T00:00:00.877" clientapp="SQLAgent - TSQL JobStep (Job 0x6B29890337552344A9872086DCFB22A9 : Step 2)" hostname="XXX" hostpid="86268" loginname="stc\XXX" isolationlevel="read committed (2)" xactid="775457003509" currentdb="39" currentdbname="DBNAME" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="sp1" line="171" stmtstart="10646" stmtend="11194" sqlhandle="0x0300270074aa560a0d4cbb0026a9000001000000000000000000000000000000000000000000000000000000">
MERGE INTO Tbl1 Tgt
USING (
SELECT DISTINCT F.Id, F.PV
FROM dbo.TblF F
INNER JOIN @TblAF A
ON A.Id = F.Id) AS Src
ON Tgt.FId = Src.Id
WHEN NOT MATCHED THEN
INSERT(FId, FType)
VALUES(Src.Id, Src.PV) </frame>
<frame procname="DBName.sp2" line="11" stmtstart="746" stmtend="804" sqlhandle="0x03002700ee9019648e33d900c5a8000001000000000000000000000000000000000000000000000000000000">
exec sp1 </frame>
<frame procname="adhoc" line="1" sqlhandle="0x01002700689c3a2a803694979e01000000000000000000000000000000000000000000000000000000000000">
exec sp2 </frame>
</executionStack>
<inputbuf>
exec sp2 </inputbuf>
</process>
<process id="process20539cb7848" taskpriority="0" logused="1048" waitresource="KEY: 39:72057594166247424 (c10f927342d3)" waittime="24" ownerId="775457003788" transactionname="DELETE" lasttranstarted="2021-08-05T16:10:03.743" XDES="0xd8bd4e03b0" lockMode="U" schedulerid="27" kpid="198392" status="suspended" spid="4564" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-08-05T16:10:01.277" lastbatchcompleted="2021-08-05T16:10:01.277" lastattention="1900-01-01T00:00:00.277" clientapp="SQLAgent - TSQL JobStep (Job 0x0C3A444DF8D29A47AC800279A54E8CDB : Step 2)" hostname="XXX" hostpid="86268" loginname="stc\XXX" isolationlevel="read committed (2)" xactid="775457003788" currentdb="39" currentdbname="DBNAME" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="DBName.sp3" line="44" stmtstart="2634" stmtend="2736" sqlhandle="0x03002700ab98f9329c5ab0004fad000001000000000000000000000000000000000000000000000000000000">
DELETE FROM Tbl1 WHERE Processed = </frame>
<frame procname="adhoc" line="1" sqlhandle="0x01002700f8771d14c08ca1dbc201000000000000000000000000000000000000000000000000000000000000">
exec sp3 </frame>
</executionStack>
<inputbuf>
exec sp3 </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594166247424" dbid="39" objectname="DBName.Tbl1" indexname="PK_FId" id="lock9286e26580" mode="X" associatedObjectId="72057594166247424">
<owner-list>
<owner id="process20539cb7848" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process233c64ffc28" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594166247424" dbid="39" objectname="DBName.Tbl1" indexname="PK_FId" id="lock1160ba17800" mode="U" associatedObjectId="72057594166247424">
<owner-list>
<owner id="process233c64ffc28" mode="U" />
</owner-list>
<waiter-list>
<waiter id="process20539cb7848" mode="U" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
версия сервера: Microsoft SQL Server 2014 (SP3-CU4) (KB4500181) - 12.0.6329.1 (X64) Jul 20 2019 21:42:29 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.3 (Build 9600: )
Может кто объяснить, как так получается, что на один и тот же ресурс в одном процессе два раза одна и та же блокировка( в данном случае U). И как устранять такого рода дедлоки?
UPD
Я вижу в resource-list два раза keylock hobtid="72057594166247424" из чего я делаю вывод, что это один и тот же ресурс (PK для таблицы). Затем в первом <keylock я вижу , что процесс process20539cb7848 уже получил X блокировку на этот ресурс. А в следующем <keylock вижу, что тот же процесс (process20539cb7848) просит U блокировку на ресурс. Т.е. процесс process20539cb7848 имея X блокировку на ресурс keylock hobtid="72057594166247424" запрашивает U блокировку на ресурс. Что это значит? В каком случает после получения X блокировки может потребоваться запросить U блокировку, разве U блокировка, не накладывается перед X блокировкой?