gpt4 book ai didi

sql-server-2005 - SQL Server 更新语句导致死锁

转载 作者:行者123 更新时间:2023-12-04 07:00:55 25 4
gpt4 key购买 nike

我有一个应用程序在不同的线程中同时运行多个 sql 语句,导致各种死锁,这些死锁似乎都来自一个表。例如下面的两个更新语句:

更新 WF SET QUEUETIME='2011-02-18 13:06:53.578', STATE = 'outbound', USER = '', TIME = null
WHERE PID = 'MessageProcessing' AND ACTIVITYID = 'Delete' AND ITEMID = '120' AND TRANID = 'Created' AND STATE = 'ready' AND USER = ''

更新 WF SET QUEUETIME='2011-02-18 13:06:53.625', STATE = 'ready', USER = '', TIME = null
WHERE PID = 'standardOutbound' AND ACTIVITYID = 'Node1' AND ITEMID = '121' AND TRANID = 'toNode1' AND STATE = '' AND USER = ''

产生以下死锁:

<deadlock-list>
<deadlock victim="process6d8e38">
<process-list>
<process id="process6d8e38" taskpriority="0" logused="272" waitresource="RID: 7:1:564:14" waittime="625" ownerId="430343" transactionname="implicit_transaction" lasttranstarted="2011-02-18T13:06:53.640" XDES="0xb44a258" lockMode="U" schedulerid="1" kpid="2632" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2011-02-18T13:06:53.640" lastbatchcompleted="2011-02-18T13:06:53.640" clientapp="jTDS" hostname="INTERWOV-FP1" hostpid="123" loginname="database1" isolationlevel="read committed (2)" xactid="430343" currentdb="7" TIMEout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="336" sqlhandle="0x0200000077e2b21749c20d3ca2ca8d4d89ea5ea29336e03e">
UPDATE WF SET QUEUETIME = @P0 , STATE = @P1 , USER = @P2 , TIME = @P3 WHERE PID = @P4 AND ACTIVITYID = @P5 AND ITEMID = @P6 AND TRANID = @P7 AND STATE = @P8 AND USER = @P9 </frame>
</executionStack>
<inputbuf>
(@P0 datetime,@P1 nvarchar(4000),@P2 nvarchar(4000),@P3 datetime,@P4 nvarchar(4000),@P5 nvarchar(4000),@P6 int,@P7 nvarchar(4000),@P8 nvarchar(4000),@P9 nvarchar(4000))UPDATE WF SET QUEUETIME = @P0 , STATE = @P1 , USER = @P2 , TIME = @P3 WHERE PID = @P4 AND ACTIVITYID = @P5 AND ITEMID = @P6 AND TRANID = @P7 AND STATE = @P8 AND USER = @P9 </inputbuf>
</process>
<process id="process8ccb68" taskpriority="0" logused="900" waitresource="RID: 7:1:564:12" waittime="625" ownerId="430341" transactionname="implicit_transaction" lasttranstarted="2011-02-18T13:06:53.623" XDES="0xaeccf48" lockMode="U" schedulerid="2" kpid="312" status="suspended" spid="53" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2011-02-18T13:06:53.640" lastbatchcompleted="2011-02-18T13:06:53.623" clientapp="jTDS" hostname="INTERWOV-FP1" hostpid="123" loginname="database1" isolationlevel="read committed (2)" xactid="430341" currentdb="7" TIMEout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="336" sqlhandle="0x0200000077e2b21749c20d3ca2ca8d4d89ea5ea29336e03e">
UPDATE WF SET QUEUETIME = @P0 , STATE = @P1 , USER = @P2 , TIME = @P3 WHERE PID = @P4 AND ACTIVITYID = @P5 AND ITEMID = @P6 AND TRANID = @P7 AND STATE = @P8 AND USER = @P9 </frame>
</executionStack>
<inputbuf>
(@P0 datetime,@P1 nvarchar(4000),@P2 nvarchar(4000),@P3 datetime,@P4 nvarchar(4000),@P5 nvarchar(4000),@P6 int,@P7 nvarchar(4000),@P8 nvarchar(4000),@P9 nvarchar(4000))UPDATE WF SET QUEUETIME = @P0 , STATE = @P1 , USER = @P2 , TIME = @P3 WHERE PID = @P4 AND ACTIVITYID = @P5 AND ITEMID = @P6 AND TRANID = @P7 AND STATE = @P8 AND USER = @P9 </inputbuf>
</process>
</process-list>
<resource-list>
<ridlock fileid="1" pageid="564" dbid="7" objectname="database1.dbo.WF" id="lock3a63dc0" mode="X" associatedObjectId="72057594077577216">
<owner-list>
<owner id="process6d8e38" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process8ccb68" mode="U" requestType="wait"/>
</waiter-list>
</ridlock>
<ridlock fileid="1" pageid="564" dbid="7" objectname="database1.dbo.WF" id="lock3a65f40" mode="X" associatedObjectId="72057594077577216">
<owner-list>
<owner id="process8ccb68" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process6d8e38" mode="U" requestType="wait"/>
</waiter-list>
</ridlock>
</resource-list>
</deadlock>
</deadlock-list>

我意识到一些死锁是不可避免的,应用程序应该处理它们(确实如此),但我不明白为什么在这种情况下会发生它们。在我的简单想法中,这两个语句应该锁定不同的行,即使它们正在更新同一行,也应该等待另一个。

任何人都可以解释为什么他们会导致死锁,或者就如何防止死锁提出任何建议?

我们在表上有 3 个非聚集索引(PID、ACTIVITYID、ITEMID、TRANID)、(ITEMID)和(PID、ACTIVITYID)。 (PID, ACTIVITYID, ITEMID, TRANID) 构成主键。我试过(有点盲目)玩弄索引,但似乎无济于事。

该应用程序在 weblogic 和 sql server 2005 上运行,我已经在 websphere 和 sql server 2008 上重现了死锁。使用 oracle 数据库时似乎不会发生这种情况,但不幸的是,这不是我们客户的选择!

非常感谢任何可以对此提供帮助或见解的人。

最佳答案

问题通常不是单独的更新,而是选择和更新的组合。考虑场景,其中事务选择一些行然后更新它。如果两个这样的事务并行运行,就会发生死锁。
最简单的解决方案是在 select 语句中使用 UPDLOCK(和可选的 ROWLOCK)提示;当然仅用于记录,之后更新 - 否则您可能会以缓慢的应用程序结束。

关于sql-server-2005 - SQL Server 更新语句导致死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5076982/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com