gpt4 book ai didi

sql - 为什么 SELECT 在死锁图中显示更新锁

转载 作者:行者123 更新时间:2023-12-03 18:48:02 24 4
gpt4 key购买 nike

我有两个 SQL 查询(MSSQL 服务器):

SELECT [Value]
FROM [dbo].[BigTable]
ORDER BY [Id] DESC
UPDATE [dbo].[BigTable]
SET [Value] = [Value]
其中 [Id] - 主聚集键。
当我在循环中无限运行它们时,我会陷入死锁,这很明显。但什么是不明显的(对我来说):为什么在死锁图中我得到“所有者模式:U”作为选择语句。
enter image description here
据我所知,select 语句只能有共享锁。在这里,我没有使用任何提示或附加事务来进行更新锁定。知道为什么我在这里看到它吗?
附上用于死锁的 XML
<deadlock-list>
<deadlock victim="process1c094ee5468">
<process-list>
<process id="process1c094ee5468" taskpriority="0" logused="0" waitresource="PAGE: 7:1:1502 " waittime="1289" ownerId="901143" transactionname="SELECT" lasttranstarted="2021-05-05T18:04:54.470" XDES="0x1c094329be8" lockMode="S" schedulerid="6" kpid="22644" status="suspended" spid="62" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2021-05-05T18:04:54.470" lastbatchcompleted="2021-05-05T18:04:54.453" lastattention="1900-01-01T00:00:00.453" clientapp="Core Microsoft SqlClient Data Provider" hostname="ALEXEY-KLIPILIN" hostpid="3132" loginname="sa" isolationlevel="read committed (2)" xactid="901143" currentdb="7" currentdbname="SampleDb" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtend="92" sqlhandle="0x02000000bf49f5138395d042205ae64888add734815151770000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
SELECT * FROM [dbo].[BigTable] ORDER BY Id DESC </inputbuf>
</process>
<process id="process1c096e1d088" taskpriority="0" logused="100" waitresource="PAGE: 7:1:1503 " waittime="1289" ownerId="901139" transactionname="UPDATE" lasttranstarted="2021-05-05T18:04:54.470" XDES="0x1c08bc84428" lockMode="X" schedulerid="4" kpid="9160" status="suspended" spid="61" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-05-05T18:04:54.470" lastbatchcompleted="2021-05-05T18:04:54.397" lastattention="1900-01-01T00:00:00.397" clientapp="Core Microsoft SqlClient Data Provider" hostname="ALEXEY-KLIPILIN" hostpid="3132" loginname="sa" isolationlevel="read committed (2)" xactid="901139" currentdb="7" currentdbname="SampleDb" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtend="88" sqlhandle="0x0200000018eeb102d311fd032bb670822f260841060b64410000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
UPDATE [dbo].[BigTable] SET [Value] = [Value] </inputbuf>
</process>
</process-list>
<resource-list>
<pagelock fileid="1" pageid="1502" dbid="7" subresource="FULL" objectname="SampleDb.dbo.BigTable" id="lock1c0884bdd00" mode="X" associatedObjectId="72057594043760640">
<owner-list>
<owner id="process1c096e1d088" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process1c094ee5468" mode="S" requestType="wait"/>
</waiter-list>
</pagelock>
<pagelock fileid="1" pageid="1503" dbid="7" subresource="FULL" objectname="SampleDb.dbo.BigTable" id="lock1c0a0a23380" mode="U" associatedObjectId="72057594043760640">
<owner-list>
<owner id="process1c094ee5468" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="process1c096e1d088" mode="X" requestType="convert"/>
</waiter-list>
</pagelock>
</resource-list>
</deadlock>
</deadlock-list>

最佳答案

这看起来像是图形表示中的一些误传。
process1c096e1d088(UPDATE)拥有一个页面级别 X锁定页面 1502 和页面级别 U锁定 1503 并尝试转换该 U锁定 X锁。 ( requestType="convert" )
process1c094ee5468(SELECT)拥有一个页面级别 S锁定 1503(与 U 锁兼容)并且正在等待页面级别 S锁定 1502。
因为页面锁1503分别在 S 举行和 U它拥有的模式 mode="U"在死锁 XML 中,并且 UI 假定它在该模式下由阻止程序持有。
当然如果SELECT事务是在请求 1502 上的锁定之前释放其在 1503 上的锁定,这种死锁不会发生,但我认为它有一个很好的理由不这样做(也许是为了阻止 1502 在扫描中被释放并使其没有下一页访问)。

关于sql - 为什么 SELECT 在死锁图中显示更新锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67404149/

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