我正在处理的API使用的数据库中发生了一些死锁。这仅在API经过负载测试时才会发生。在初步调查和研究期间,一些进口指数似乎缺失,现在已经应用。这似乎解决了死锁问题。在应用索引之前,SQL正在执行索引扫描。应用索引后,SQL正在执行索引搜索。
这个问题的原因是为了巩固我对僵局的理解。我仍然有点困惑,为什么没有索引,select语句导致MS SQL中的独占(X)锁?
我认为,这纯粹是因为我不了解死锁图。从我可以看到,下图中的2个进程都在做选择..那么怎么能导致独占(X)锁?图表上是否还有某些内容?
这是没有额外索引的死锁图:
...这里是XML(来自该图:
<deadlock-list>
<deadlock victim="process4c3708">
<process-list>
<process id="process4c3708" taskpriority="0" logused="1580" waitresource="KEY: 5:72057594038910976 (a94bedf44228)" waittime="99" ownerId="13602992" transactionname="user_transaction" lasttranstarted="2012-10-03T10:59:34.830" XDES="0x8cbf23b0" lockMode="S" schedulerid="3" kpid="7588" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2012-10-03T10:59:35.027" lastbatchcompleted="2012-10-03T10:59:35.020" clientapp=".Net SqlClient Data Provider" hostname="DEVMACHINE" hostpid="8440" loginname="user" isolationlevel="read committed (2)" xactid="13602992" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="170" stmtend="728" sqlhandle="0x02000000b3a88339052734f326b9dbb95deb1d46fe4d192d">
select basefolder1_.Identifier as col_0_0_ from TradeInfo tradepr0_ inner join BaseFolder basefolder1_ on tradepr0_.BaseFolderId=basefolder1_.Id where basefolder1_.BoxId=@p0 and tradepr0_.PersonId=@p1 and tradepr0_.CurrentTrade=1 and tradepr0_.IsActive=1; </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
(@p0 uniqueidentifier,@p1 uniqueidentifier,@p2 uniqueidentifier,@p3 uniqueidentifier)select basefolder1_.Identifier as col_0_0_ from TradeInfo tradepr0_ inner join BaseFolder basefolder1_ on tradepr0_.BaseFolderId=basefolder1_.Id where basefolder1_.BoxId=@p0 and tradepr0_.PersonId=@p1 and tradepr0_.CurrentTrade=1 and tradepr0_.IsActive=1;
select basefolder1_.Identifier as col_0_0_ from TradeInfo tradepr0_ inner join BaseFolder basefolder1_ on tradepr0_.BaseFolderId=basefolder1_.Id where basefolder1_.BoxId=@p2 and tradepr0_.PersonId=@p3 and tradepr0_.SuspendedTrade=1 and tradepr0_.IsSuspended=1;
</inputbuf>
</process>
<process id="process5dd4c8" taskpriority="0" logused="1580" waitresource="KEY: 5:72057594038910976 (b34811986aff)" waittime="301" ownerId="13602927" transactionname="user_transaction" lasttranstarted="2012-10-03T10:59:34.660" XDES="0xafb9f950" lockMode="S" schedulerid="4" kpid="2076" status="suspended" spid="61" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2012-10-03T10:59:35.020" lastbatchcompleted="2012-10-03T10:59:35.020" clientapp=".Net SqlClient Data Provider" hostname="DEVMACHINE" hostpid="8440" loginname="user" isolationlevel="read committed (2)" xactid="13602927" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="170" stmtend="728" sqlhandle="0x02000000b3a88339052734f326b9dbb95deb1d46fe4d192d">
select basefolder1_.Identifier as col_0_0_ from TradeInfo tradepr0_ inner join BaseFolder basefolder1_ on tradepr0_.BaseFolderId=basefolder1_.Id where basefolder1_.BoxId=@p0 and tradepr0_.PersonId=@p1 and tradepr0_.CurrentTrade=1 and tradepr0_.IsActive=1; </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
(@p0 uniqueidentifier,@p1 uniqueidentifier,@p2 uniqueidentifier,@p3 uniqueidentifier)select basefolder1_.Identifier as col_0_0_ from TradeInfo tradepr0_ inner join BaseFolder basefolder1_ on tradepr0_.BaseFolderId=basefolder1_.Id where basefolder1_.BoxId=@p0 and tradepr0_.PersonId=@p1 and tradepr0_.CurrentTrade=1 and tradepr0_.IsActive=1;
select basefolder1_.Identifier as col_0_0_ from TradeInfo tradepr0_ inner join BaseFolder basefolder1_ on tradepr0_.BaseFolderId=basefolder1_.Id where basefolder1_.BoxId=@p2 and tradepr0_.PersonId=@p3 and tradepr0_.SuspendedTrade=1 and tradepr0_.IsSuspended=1;
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594038910976" dbid="5" objectname="ccp.dbo.TradeInfo" indexname="PK__Activity__3214EC07060DEAE8" id="lock8011dd00" mode="X" associatedObjectId="72057594038910976">
<owner-list>
<owner id="process5dd4c8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process4c3708" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594038910976" dbid="5" objectname="ccp.dbo.TradeInfo" indexname="PK__Activity__3214EC07060DEAE8" id="lock8a864e00" mode="X" associatedObjectId="72057594038910976">
<owner-list>
<owner id="process4c3708" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process5dd4c8" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
答案 0 :(得分:3)
它不会(没有锁定提示)
据推测,在同一事务中有一个前面的语句(未在死锁图中显示)实际上获得了X
锁。
请注意logused="1580"
如果语句是独立的SELECT
答案 1 :(得分:2)
死锁XML中的SELECT都没有实际获取X锁。死锁中涉及的两个资源目前在X模式下拥有,在S模式下请求。这意味着每个事务都以前锁定了资源(在本例中为密钥),也许它已经运行了更新/插入该行的DML语句。 SELECT语句只想读取行,因此它们请求S模式。