都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo

都内でサラリーマンやってます。SQL Server を中心とした (2023年からは Azure も。) マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。英語の勉強のため、英語の

デッドロックについて説明してみる - その 5 ( そして、さらに、デッドロックグラフも見てみる ) -

 本日最後のお仕事、子供とカードゲームのお買い物です。カード購入後、スリーブというビニール製のケースに一枚づつ収納します。見ていてかなり面倒臭そうですが、子供にとっては楽しい作業のようです。
f:id:koogucc11:20161029172247j:plain

 中でも大事なカードは、スリーブを二重し、収納するようです。( 超がつくほどレアなカードは、5重にする場合もあるそうです... )
f:id:koogucc11:20161029173859j:plain

 うーん、自分には理解し難い世界....子供の作業を待っているだけなのも暇なので、記事書きますww 今回は、デッドロックグラフについてです。SQL Server Profiler を使用してデッドロックグラフを取得してみましょう。SQL Server Profiler で下図のように設定し、実行ボタンをクリックします。
f:id:koogucc11:20161029174214p:plain

 下記の記事のクエリを実行し、デッドロックを発生させます。
ryuchan.hatenablog.com

 デッドロックが発生しました。
f:id:koogucc11:20161029174450p:plain

 SQL Server Profiler を参照します。デッドロックが発生しているのがわかりますね。
f:id:koogucc11:20161029174839p:plain

 デッドロックグラフは、トレースフラグの 1222 と同様です。出力している中身も XML であること以外はすべて同様です。

<deadlock-list>
 <deadlock victim="process12b55fa24e8">
  <process-list>
   <process id="process12b55fa24e8" taskpriority="0" logused="144" waitresource="KEY: 10:72057594047365120 (61a06abd401c)" waittime="4850" ownerId="165452" transactionname="user_transaction" lasttranstarted="2016-10-29T17:43:31.890" XDES="0x12bb954b778" lockMode="U" schedulerid="2" kpid="16072" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-10-29T17:43:31.857" lastbatchcompleted="2016-10-29T17:43:31.857" lastattention="1900-01-01T00:00:00.857" clientapp="Microsoft SQL Server Management Studio - クエリ" hostname="xxxxxxxx" hostpid="13792" loginname="xxxxxxxx\xxxxxxxx" isolationlevel="read committed (2)" xactid="165452" currentdb="10" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
    <executionStack>
     <frame procname="adhoc" line="17" stmtstart="748" stmtend="984" sqlhandle="0x020000002ac21b1c626aefe609b1bd5c778fde060fd0e1d90000000000000000000000000000000000000000">
unknown     </frame>
     <frame procname="adhoc" line="17" stmtstart="748" stmtend="984" sqlhandle="0x02000000b3207c1e426c24e8f6554c9a244fc1f935b220440000000000000000000000000000000000000000">
unknown     </frame>
    </executionStack>
    <inputbuf>
DECLARE @Error_Message  NVARCHAR(MAX);
DECLARE @Error_Severity INT;
DECLARE @Error_State    INT;

WHILE 0 = 0
BEGIN
    BEGIN TRY
        BEGIN TRAN 
        -- ProductID = 1 のデータを更新する。
        UPDATE 
            Production.Product
        SET Name = N&apos;Adjustable Race&apos;
        WHERE 
            ProductID = 1 

        -- ProductID = 2 のデータを更新する。
        UPDATE 
            Production.Product
        SET Name = N&apos;Bearing Ball&apos; 
        WHERE 
            ProductID = 2 

        COMMIT TRAN
    END TRY

    -- 例外をキャッチしたら、メッセージを出力して処理を終了する。	
    BEGIN CATCH
        SET @Error_Message  = ERROR_MESSAGE();
        SET @Error_Severity = ERROR_SEVERITY();
        SET @Error_State    = ERROR_STATE();
        RAISERROR(@Error_Message, @Error_Severity, @Error_State);
        BREAK;
    END CATCH
END    </inputbuf>
   </process>
   <process id="process12ba4998ca8" taskpriority="0" logused="144" waitresource="KEY: 10:72057594047365120 (8194443284a0)" waittime="4850" ownerId="165455" transactionname="user_transaction" lasttranstarted="2016-10-29T17:43:31.890" XDES="0x12bb954ad28" lockMode="U" schedulerid="2" kpid="16148" status="suspended" spid="57" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-10-29T17:43:30.537" lastbatchcompleted="2016-10-29T17:43:30.510" lastattention="1900-01-01T00:00:00.510" clientapp="Microsoft SQL Server Management Studio - クエリ" hostname="xxxxxxxx" hostpid="13792" loginname="xxxxxxxx\xxxxxxxx" isolationlevel="read committed (2)" xactid="165455" currentdb="10" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
    <executionStack>
     <frame procname="adhoc" line="17" stmtstart="742" stmtend="982" sqlhandle="0x020000002ac21b1c626aefe609b1bd5c778fde060fd0e1d90000000000000000000000000000000000000000">
unknown     </frame>
     <frame procname="adhoc" line="17" stmtstart="742" stmtend="982" sqlhandle="0x02000000b865d60581449ff5a87c353f302f7be636728a490000000000000000000000000000000000000000">
unknown     </frame>
    </executionStack>
    <inputbuf>
DECLARE @Error_Message  NVARCHAR(MAX);
DECLARE @Error_Severity INT;
DECLARE @Error_State    INT;

WHILE 0 = 0
BEGIN
    BEGIN TRY
        BEGIN TRAN
        -- ProductID = 2 のデータを更新する。
        UPDATE 
            Production.Product
        SET Name = N&apos;Bearing Ball&apos; 
        WHERE 
            ProductID = 2 

        -- ProductID = 1 のデータを更新する。
        UPDATE 
            Production.Product
        SET Name = N&apos;Adjustable Race&apos;
        WHERE 
            ProductID = 1 
        COMMIT TRAN
    END TRY

    -- 例外をキャッチしたら、メッセージを出力して処理を終了する。
    BEGIN CATCH
        SET @Error_Message  = ERROR_MESSAGE();
        SET @Error_Severity = ERROR_SEVERITY();
        SET @Error_State    = ERROR_STATE();
        RAISERROR(@Error_Message, @Error_Severity, @Error_State);
        BREAK;
    END CATCH
END    </inputbuf>
   </process>
  </process-list>
  <resource-list>
   <keylock hobtid="72057594047365120" dbid="10" objectname="AdventureWorks.Production.Product" indexname="PK_Product_ProductID" id="lock12b5b3dc980" mode="X" associatedObjectId="72057594047365120">
    <owner-list>
     <owner id="process12ba4998ca8" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="process12b55fa24e8" mode="U" requestType="wait"/>
    </waiter-list>
   </keylock>
   <keylock hobtid="72057594047365120" dbid="10" objectname="AdventureWorks.Production.Product" indexname="PK_Product_ProductID" id="lock12b5b3d7480" mode="X" associatedObjectId="72057594047365120">
    <owner-list>
     <owner id="process12b55fa24e8" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="process12ba4998ca8" mode="U" requestType="wait"/>
    </waiter-list>
   </keylock>
  </resource-list>
 </deadlock>
</deadlock-list>

 個人的には、デッドロックの検出に関しては 1222 が一番見やすいです。1222 と 1204 を組み合わせてもよいかもしれませんね。

 恐るべし、カードゲーム.....