为什么 SELECT 在死锁图中显示更新锁
Why SELECT shows Update lock in deadlock graph
我有两个 SQL 查询(MSSQL 服务器):
SELECT [Value]
FROM [dbo].[BigTable]
ORDER BY [Id] DESC
和
UPDATE [dbo].[BigTable]
SET [Value] = [Value]
其中 [Id] - 主聚集键。
当我在循环中无限地 运行 它们时,我陷入了死锁,这很明显。但不明显的是(对我而言):为什么在死锁图上我得到“Owner mode: U” for select statement。
据我所知,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
)在页面 1502 上持有一个页面级 X
锁,在 1503 上持有一个页面级 U
锁,并且正在尝试转换 U
锁到 X
锁。 (requestType="convert"
)
process1c094ee5468 (SELECT
) 在 1503 上持有页级 S
锁(与 U
锁兼容)并正在等待页级 S
锁在 1502.
因为页面锁 1503
在 S
和 U
模式下都持有,所以它在死锁 XML 和 [=35] 中有 mode="U"
=] 假定它在该模式下被拦截器持有。
当然,如果 SELECT
事务是在请求 1502 上的锁之前释放其在 1503 上的锁,则不会出现此死锁,但我认为它有充分的理由不这样做(也许是为了停止1502 正在扫描中途解除分配并使其无法访问下一页)。
我有两个 SQL 查询(MSSQL 服务器):
SELECT [Value]
FROM [dbo].[BigTable]
ORDER BY [Id] DESC
和
UPDATE [dbo].[BigTable]
SET [Value] = [Value]
其中 [Id] - 主聚集键。
当我在循环中无限地 运行 它们时,我陷入了死锁,这很明显。但不明显的是(对我而言):为什么在死锁图上我得到“Owner mode: U” for select statement。
据我所知,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
)在页面 1502 上持有一个页面级 X
锁,在 1503 上持有一个页面级 U
锁,并且正在尝试转换 U
锁到 X
锁。 (requestType="convert"
)
process1c094ee5468 (SELECT
) 在 1503 上持有页级 S
锁(与 U
锁兼容)并正在等待页级 S
锁在 1502.
因为页面锁 1503
在 S
和 U
模式下都持有,所以它在死锁 XML 和 [=35] 中有 mode="U"
=] 假定它在该模式下被拦截器持有。
当然,如果 SELECT
事务是在请求 1502 上的锁之前释放其在 1503 上的锁,则不会出现此死锁,但我认为它有充分的理由不这样做(也许是为了停止1502 正在扫描中途解除分配并使其无法访问下一页)。