SQLException:处理 2 个不同的表时出现死锁错误
SQLException : Deadlock error when processing 2 different tables
我有死锁错误:
Transaction (Process ID 91) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
图像死锁(https://i.stack.imgur.com/rDyxP.png)
Sp 91 是商店 Katzkin.dbo.ItemsAirBags_DX_IdItem:
delete ItemsAirBags
from ItemsAirBags
where IdItem = @IdItem
Sp291 是商店 Katzkin.dbo.Items_TX_Description:
select *
from items
where description = @description or left(description,5) = @description
我从 redgate 下载的完整 deadlock.xml
:
<deadlock>
<victim-list>
<victimProcess id="process366a0a5848" />
</victim-list>
<process-list>
<process id="process366a0a5848" taskpriority="0" logused="6424" waitresource="KEY: 6:72057609466478592 (56dfc8bc1bd3)" waittime="134" ownerId="2620704196" transactionname="user_transaction" lasttranstarted="2021-01-25T10:48:53.610" XDES="0x4462dd4490" lockMode="U" schedulerid="11" kpid="14292" status="suspended" spid="91" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-01-25T10:48:53.690" lastbatchcompleted="2021-01-25T10:48:53.687" lastattention="2021-01-25T08:32:04.567" clientapp=".Net SqlClient Data Provider" hostname="SQLSERVER" hostpid="17172" loginname="KatCa" isolationlevel="read committed (2)" xactid="2620704196" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="Katzkin.dbo.ItemsAirBags_DX_IdItem" line="2" stmtstart="136" stmtend="258" sqlhandle="0x030006006b1f922228e7730050ab000001000000000000000000000000000000000000000000000000000000">
delete ItemsAirBags from ItemsAirBags
where IdItem = @IdIte </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 580001643] </inputbuf>
</process>
<process id="process3dc4191468" taskpriority="0" logused="34720" waitresource="KEY: 6:72057609931325440 (b015ce3d2676)" waittime="62" ownerId="2620704065" transactionname="user_transaction" lasttranstarted="2021-01-25T10:48:53.500" XDES="0x3d45478490" lockMode="S" schedulerid="6" kpid="1500" status="suspended" spid="291" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2021-01-25T10:48:53.760" lastbatchcompleted="2021-01-25T10:48:53.760" lastattention="2021-01-25T08:30:50.683" clientapp=".Net SqlClient Data Provider" hostname="SQLSERVER" hostpid="30552" loginname="KatCa" isolationlevel="read committed (2)" xactid="2620704065" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="Katzkin.dbo.Items_TX_Description" line="4" stmtstart="172" stmtend="348" sqlhandle="0x030006008513045381f88c002da3000001000000000000000000000000000000000000000000000000000000">
Select * from items
where description=@description or left(description,5)=@descriptio </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 1392776069] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057609466478592" dbid="6" objectname="Katzkin.dbo.ItemsAirBags" indexname="PK_ItemsAirBags" id="lock3ca39db480" mode="X" associatedObjectId="72057609466478592">
<owner-list>
<owner id="process3dc4191468" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process366a0a5848" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057609931325440" dbid="6" objectname="Katzkin.dbo.Items" indexname="PK_Items" id="lock3f52da2100" mode="X" associatedObjectId="72057609931325440">
<owner-list>
<owner id="process366a0a5848" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process3dc4191468" mode="S" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
我们在两个不同的表上但导致了死锁,我不明白原因以及如何解决它。
关于如何解决这些问题有什么想法吗?
如死锁图所示,您有 2 个存储过程,它们都试图 update/access 相同的行,但出于某种原因,其中一个是 updating/accessing ItemsAirBags
table 第一个和 Items
table 第二个和另一个相反顺序的存储过程。这就是造成僵局的原因。如果您使两个存储过程 update/access 和 table 的顺序相同,您将消除死锁。
当您处理父子情况时,有时需要在更新父项和子项之前对计划更新的子行进行更新锁定。
您要确保始终 update/access 您的 table 顺序相同,因为这样第一个存储过程将阻塞第二个存储过程(这是您想要的)而不是死锁.
注意:这些存储过程中发生的事情一定比您的代码显示的要多,因为就目前而言,不会有死锁。进程 process3dc4191468
以某种方式在 ItemsAirBags
上有排他锁,这不是显示的 SQL 的一部分。
我有死锁错误:
Transaction (Process ID 91) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
图像死锁(https://i.stack.imgur.com/rDyxP.png)
Sp 91 是商店 Katzkin.dbo.ItemsAirBags_DX_IdItem:
delete ItemsAirBags
from ItemsAirBags
where IdItem = @IdItem
Sp291 是商店 Katzkin.dbo.Items_TX_Description:
select *
from items
where description = @description or left(description,5) = @description
我从 redgate 下载的完整 deadlock.xml
:
<deadlock>
<victim-list>
<victimProcess id="process366a0a5848" />
</victim-list>
<process-list>
<process id="process366a0a5848" taskpriority="0" logused="6424" waitresource="KEY: 6:72057609466478592 (56dfc8bc1bd3)" waittime="134" ownerId="2620704196" transactionname="user_transaction" lasttranstarted="2021-01-25T10:48:53.610" XDES="0x4462dd4490" lockMode="U" schedulerid="11" kpid="14292" status="suspended" spid="91" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-01-25T10:48:53.690" lastbatchcompleted="2021-01-25T10:48:53.687" lastattention="2021-01-25T08:32:04.567" clientapp=".Net SqlClient Data Provider" hostname="SQLSERVER" hostpid="17172" loginname="KatCa" isolationlevel="read committed (2)" xactid="2620704196" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="Katzkin.dbo.ItemsAirBags_DX_IdItem" line="2" stmtstart="136" stmtend="258" sqlhandle="0x030006006b1f922228e7730050ab000001000000000000000000000000000000000000000000000000000000">
delete ItemsAirBags from ItemsAirBags
where IdItem = @IdIte </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 580001643] </inputbuf>
</process>
<process id="process3dc4191468" taskpriority="0" logused="34720" waitresource="KEY: 6:72057609931325440 (b015ce3d2676)" waittime="62" ownerId="2620704065" transactionname="user_transaction" lasttranstarted="2021-01-25T10:48:53.500" XDES="0x3d45478490" lockMode="S" schedulerid="6" kpid="1500" status="suspended" spid="291" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2021-01-25T10:48:53.760" lastbatchcompleted="2021-01-25T10:48:53.760" lastattention="2021-01-25T08:30:50.683" clientapp=".Net SqlClient Data Provider" hostname="SQLSERVER" hostpid="30552" loginname="KatCa" isolationlevel="read committed (2)" xactid="2620704065" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="Katzkin.dbo.Items_TX_Description" line="4" stmtstart="172" stmtend="348" sqlhandle="0x030006008513045381f88c002da3000001000000000000000000000000000000000000000000000000000000">
Select * from items
where description=@description or left(description,5)=@descriptio </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 1392776069] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057609466478592" dbid="6" objectname="Katzkin.dbo.ItemsAirBags" indexname="PK_ItemsAirBags" id="lock3ca39db480" mode="X" associatedObjectId="72057609466478592">
<owner-list>
<owner id="process3dc4191468" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process366a0a5848" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057609931325440" dbid="6" objectname="Katzkin.dbo.Items" indexname="PK_Items" id="lock3f52da2100" mode="X" associatedObjectId="72057609931325440">
<owner-list>
<owner id="process366a0a5848" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process3dc4191468" mode="S" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
我们在两个不同的表上但导致了死锁,我不明白原因以及如何解决它。 关于如何解决这些问题有什么想法吗?
如死锁图所示,您有 2 个存储过程,它们都试图 update/access 相同的行,但出于某种原因,其中一个是 updating/accessing ItemsAirBags
table 第一个和 Items
table 第二个和另一个相反顺序的存储过程。这就是造成僵局的原因。如果您使两个存储过程 update/access 和 table 的顺序相同,您将消除死锁。
当您处理父子情况时,有时需要在更新父项和子项之前对计划更新的子行进行更新锁定。
您要确保始终 update/access 您的 table 顺序相同,因为这样第一个存储过程将阻塞第二个存储过程(这是您想要的)而不是死锁.
注意:这些存储过程中发生的事情一定比您的代码显示的要多,因为就目前而言,不会有死锁。进程 process3dc4191468
以某种方式在 ItemsAirBags
上有排他锁,这不是显示的 SQL 的一部分。