私は実際に、「DTCXact」という名前の少なくとも1つのトランザクションをすべて含む定期的に発生するいくつかのデッドロックを分析して解決しようとしています。
本番サーバーに対して次のクエリを繰り返し実行します。
_SELECT DTAT.transaction_id ,
DTAT.[name] ,
DTAT.transaction_begin_time ,
CASE DTAT.transaction_type
WHEN 1 THEN 'Read/write'
WHEN 2 THEN 'Read-only'
WHEN 3 THEN 'System'
WHEN 4 THEN 'Distributed'
END AS transaction_type ,
CASE DTAT.transaction_state
WHEN 0 THEN 'Not fully initialized'
WHEN 1 THEN 'Initialized, not started'
WHEN 2 THEN 'Active'
WHEN 3 THEN 'Ended' -- only applies to read-only transactions
WHEN 4 THEN 'Commit initiated'-- distributed transactions only
WHEN 5 THEN 'Prepared, awaiting resolution'
WHEN 6 THEN 'Committed'
WHEN 7 THEN 'Rolling back'
WHEN 8 THEN 'Rolled back'
END AS transaction_state ,
CASE DTAT.dtc_state
WHEN 1 THEN 'Active'
WHEN 2 THEN 'Prepared'
WHEN 3 THEN 'Committed'
WHEN 4 THEN 'Aborted'
WHEN 5 THEN 'Recovered'
END AS dtc_state
FROM sys.dm_tran_active_transactions DTAT
INNER JOIN sys.dm_tran_session_transactions DTST
ON DTAT.transaction_id = DTST.transaction_id
WHERE [DTST].[is_user_transaction] = 1
ORDER BY DTAT.transaction_begin_time
_
常にこのサンプルと同様の結果が表示されます。
2414848764; DTCXact; 2016-01-28 10:24:41.983;配布済み;コミット済み;コミット済み2414896908; DTCXact; 2016-01-28 10:26:05.847;配布済み;コミット済み2414903917; DTCXact; 2016-01-28 10 :26:29.017; Distributed; Committed; Committed 2414918503; user_transaction; 2016-01-28 10:27:06.823; Read/write; Active; NULL 2414918551; DTCXact; 2016-01-28 10:27:06.973; Distributed; Committed ;関与する
この結果は、ほとんどのトランザクションが分散として実行されることを示しています。なぜか全然わかりません。一部のサーバーは2つのノードでクラスター化されています。他はそうではありません。結果は似ています。
事実:
remote trans proc
_が0に設定されています。Begin DISTRIBUTED Transaction
_または_SET REMOTE_PROC_TRANSACTIONS
_の使用法が見つかりませんでしたTransactionScope
の定義/使用方法なし//COM+ Transaction mgr using "Service without Components" model built according to System.Transactions.TransactionScope (NET 2). I don't know what this means.
これらのトランザクションを引き起こすasp.net Webアプリケーションは、通常、常に同じSQL-Server上の同じデータベースからデータを読み書きします。例外が非常に少ない場合があり、特に夜間にデータをコピーする場合に実行されますが、トランザクションのメジャーが1日中分散しているとは思わないでしょう。
分散トランザクションを実行していることがわかったSPIDの動作を追跡しました。
トレースのサンプル結果は次のとおりです。何十もの_RPC:Completed
_イベントが2つのDTCTransaction
イベントに続いて表示されます(1番目:EventSubClass = "_Enlisting in a DTC transaction
_"、2番目のEventSubclass = "_Propagate Transaction
_ ")。すべて同じDBをターゲットにします。 _TM:Promote Tran xxx
_イベントは発生しません。
これらのクエリが、同じデータベースを使用してジョブを実行する.net WindowsサービスのIIS(Webアプリケーションがホストされている場所))で実行されていることがわかりました。 DTCを引き起こすか。
同様の質問や回答を見つけることなく、ウェブを検索しました。何が原因なのでしょうか?または、これを理解するためにどのような知識を見逃しますか?
1つのセッションをプロファイリングして、トランザクションが分散にプロモートされるかどうか、またはいつプロモートされるかを確認しましたか?たとえば、次を使用してサーバー側のトレースを使用します。 DTCTransaction
(およびおそらくTM: Promote Tran xxx
)イベントクラス。 Windowsでは、詳細な DTCアクティビティ を監視することもできます。
1つのSPIDがいくつかの代表的な作業を行っている間に、1つのSPIDについて考えられるすべての接続、実行、およびトランザクション関連のイベントをプロファイルします。注:プロファイリングは、サーバー側のトレースまたは同等の拡張イベントを使用して、オーバーヘッドのためにテストシステムで行うのが最適です。 実際には他にオプションがない場合は、ローカルテストインスタンス以外ではプロファイラーUIを使用しないでください。
アプリケーションのソースコードを確認したり、トランザクションの使用について開発者に話しかけることができなかった場合、これが原因を特定するための方法です。
また、アプリケーション、そのデータアクセス層、またはクライアントドライバーが、2番目のローカルデータベースにアクセスしたとき、または同じトランザクションで2番目の接続を使用したときにトランザクションを昇格するように設定されている場合もあります。明示的なBEGIN DISTRIBUTED TRANSACTION
が存在することもあります。おそらくTransactionScope
(または類似の)が、複数の接続を持つADO.NETで使用されています。見る:
多くの可能性がありますが、トレース/プロファイリングは、少なくともどこに調査を集中すべきかについての手掛かりを与えます。
私の推測では、アプリケーション開発者が.NET接続とトランザクションを使用している方法の意図しない副作用である可能性がである可能性が高いです。方法IISが構成されています。
分散トランザクションが何らかの方法で "Transaction Mgr"クラスに関連付けられているようです。コードに明示的なTransactionScopeを含める必要はありません。これは1つの一般的なベクトルにすぎません。
DTCとSQL Serverへの影響を監視しながらアプリケーションコード(およびデータアクセスコンポーネント)をステップ実行することは、分散トランザクションが呼び出される、または参加する場所、時期、および理由を正確に判断するための最良の方法です。
廃止された質問は編集されましたが、他の原因には次のものがあります。
remote proc transaction promotion
がtrueに設定されているリンクサーバー。これにより、ローカルトランザクションが分散トランザクションに昇格する可能性があります。
レガシー構成設定remote trans proc
sys.configurationsで、「リモートサーバー」と共に使用した場合。 SET REMOTE_PROC_TRANSACTIONS
セッションオプションもご覧ください。
MARSサポートが利用可能になる前にアプリは作成されましたか?
1つのトランザクション内でアプリが開く接続の数を確認します。複数の接続を開き、それらを同じトランザクションに参加させると、接続が同じデータベースへの接続であっても、トランザクションはDTCに昇格します。