Fru*_*aun 1 sql-server deadlock locking blocking deadlock-graph
我试图理解为什么 SQL Server (2014) 在死锁场景中放置独占键锁。我已将整个死锁图粘贴在下面。
我很困惑,因为死锁发生在两个 SELECT 语句之间,两者都作为单个 READ COMMITTED 语句运行,而不是在事务内运行(因此同一事务中的其他地方没有发生更新等)。
我相信发生死锁是因为每个进程都在索引上创建一系列键锁,并且由于获取它们的顺序,所以发生了死锁。但是,如果进程仅创建共享锁,则不应出现死锁(根据我的理解)!
所以根本问题是 - 为什么这些 SELECT 语句会获取独占键锁?
我希望这只是我对锁定的误解。任何建议将不胜感激。
<deadlock>
<victim-list>
<victimProcess id="processd7f647848" />
</victim-list>
<process-list>
<process id="processd7f647848" taskpriority="0" logused="25948" waitresource="KEY: 32:72057594051428352 (e2d15ad895e9)" waittime="5014" ownerId="394724294049" transactionname="user_transaction" lasttranstarted="2022-04-06T09:46:18.770" XDES="0x67bf873350" lockMode="S" schedulerid="15" kpid="26196" status="suspended" spid="306" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2022-04-06T09:46:18.783" lastbatchcompleted="2022-04-06T09:46:18.783" lastattention="1900-01-01T00:00:00.783" clientapp=".Net SqlClient Data Provider" hostname="myhost" hostpid="1500" loginname="myuser" isolationlevel="read committed (2)" xactid="394724294049" currentdb="32" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="MyDatabase.Main.GetMessages" line="154" stmtstart="11934" stmtend="12156" sqlhandle="0x03002000ebd98264d1bfae0066ae000001000000000000000000000000000000000000000000000000000000">
SELECT ID, Message FROM [dbo].[Messages] WHERE MessageType = @Type </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 32 Object Id = 1686297067] </inputbuf>
</process>
<process id="processd7f61f848" taskpriority="0" logused="27364" waitresource="KEY: 32:72057594051428352 (1b9d314f70e5)" waittime="6194" ownerId="394724293688" transactionname="user_transaction" lasttranstarted="2022-04-06T09:46:18.763" XDES="0x12ca804d350" lockMode="S" schedulerid="10" kpid="27008" status="suspended" spid="487" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2022-04-06T09:46:18.780" lastbatchcompleted="2022-04-06T09:46:18.780" lastattention="1900-01-01T00:00:00.780" clientapp=".Net SqlClient Data Provider" hostname="myhost" hostpid="1500" loginname="myuser" isolationlevel="read committed (2)" xactid="394724293688" currentdb="32" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="MyDatabase.Main.GetMessages" line="154" stmtstart="11934" stmtend="12156" sqlhandle="0x03002000ebd98264d1bfae0066ae000001000000000000000000000000000000000000000000000000000000">
SELECT ID, Message FROM [dbo].[Messages] WHERE MessageType = @Type </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 32 Object Id = 1686297067] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594051428352" dbid="32" objectname="MyDatabase.dbo.Messages" indexname="IX_Messages_Type" id="lockba5d041f80" mode="X" associatedObjectId="72057594051428352">
<owner-list>
<owner id="processd7f61f848" mode="X" />
</owner-list>
<waiter-list>
<waiter id="processd7f647848" mode="S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594051428352" dbid="32" objectname="MyDatabase.dbo.Messages" indexname="IX_Messages_Type" id="lock11fad883600" mode="X" associatedObjectId="72057594051428352">
<owner-list>
<owner id="processd7f647848" mode="X" />
</owner-list>
<waiter-list>
<waiter id="processd7f61f848" mode="S" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
Run Code Online (Sandbox Code Playgroud)
你应该做的第一件事是运行这个:
SELECT sp = OBJECT_NAME(1686297067, 32);
Run Code Online (Sandbox Code Playgroud)
这将为您提供属于死锁一部分的存储过程的名称,而 SQL Server 不会费心去自行找出该名称。
这应该会让您看到与您正在查看的死锁图更密切相关的语句。
我之前在这里讨论过这个问题:Deadlock Graph Frustrations,其中看似不相关的语句位于死锁 XML 中。
归档时间: |
|
查看次数: |
928 次 |
最近记录: |