0

作業中の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>
4

2 に答える 2

3

そうではありません(ヒントをロックしないと)

おそらく、実際にロックを取得した同じトランザクション(デッドロックグラフには表示されていません)に先行するステートメントがありましたX

logused="1580"ステートメントがスタンドアロンの場合も発生しないことに注意してくださいSELECT

于 2012-10-03T11:16:27.837 に答える
2

デッドロックXMLのSELECTは、実際にはXロックを取得しません。デッドロックに関係する2つのリソースは、現在Xモードで所有されており、Sモードで要求されています。これは、各トランザクションが以前にリソース(この場合はキー)をロックしたことを意味します。おそらく、その行を更新/挿入したDMLステートメントを実行していました。SELECTステートメントは行を読み取りたいだけなので、Sモードを要求します。

于 2012-10-03T11:20:27.247 に答える