0

サーバー側で Linq2Sql を使用している Web サイトがあります。

ときどき (まだ原因は特定されていませんが)、開いているトランザクションが原因で Web サイト全体がロックされます。でブロッキング プロセスを確認master..sysprocessesできます。このプロセス ID から、ロックを実行しているプロセス ID が私の Web サイトの IIS プロセスであり、open_tran1 であるDBCC inputbufferことがわかりselect ... from MyTableます。オブジェクトの読み込み時に Linq2Sql によって生成されます。とにかく、私が書いた SQL ではないことは確かです。

古い「BeginTransaction .. Commit/RollbackTransaction」ブロックがないかコードベース全体をスキャンしました。なだ。すべてusing (var ts = new TransactionScope()) { ... }ブロックを使用しています。IIS プロセスにアタッチし、別のスレッドのクエリがブロックされたときにタイムアウト例外をキャッチしました。トランザクション ブロック内にぶら下がっている他のスレッドはありません。その間、ブロッキングプロセスはまったくなくなりません。

これをさらにトラブルシューティングする方法についてのアイデアはありますか?

4

1 に答える 1

1

まず、明らかなことを調査してください。そのようなトランザクションが存在する場合は、ASP プロセスにデバッガーをアタッチし、すべてのスレッドをチェックし、トランザクション スコープ内でブロック/スピンしているスレッドがないことを確認します。非同期 ADO.Net 呼び出しを使用する場合 ( .BeginExecuteReader) はより複雑ですが、LINQ を使用する場合、非同期 DB 呼び出しを使用する可能性はほとんどありません。

私見で最も可能性の高い原因は、クライアント プロセス内 (ASP.Net プロセス内) でデッドロック チェーンが完了するデッドロック状態です。これには、クライアントで何らかの形式のロックが必要です (C#lockなど)。ロックを保持しているスレッドが DB に入ってブロックしているときに、クライアントで実行されている最初のスレッドをブロックしている DB ロックを持つ別のスレッドが保持を必要としているときに発生します。最初のスレッドで。IS はデッドロックですが、チェーン ループには SQL Server の alock とクライアント プロセスの別のロックが含まれているため、SQL Server のデッドロック モニターでは検出できません。このサイトの作成者自身がこの問題に遭遇しました、誰にでも起こりうることです。まあ、プロセスロックを保持している間、DB呼び出しのような高価な可能性のある外部呼び出しをブロックする人は誰でも、これはマルチスレッドプログラミングでそれをしないという最初のルールです...私は分岐します。アプリに明示的なロックがなくても、そのようなロックを持つコンポーネントがあります。Log4Net。上記で推奨されているように、プロセスにデバッガーをアタッチすると、問題が表示されます。

別の可能性のある容疑者は、分散トランザクションへのトランザクションの登録です。TransactionScope単一のトランザクション スコープ内で複数の接続 (複数の Linq データ コンテキストなど) が使用されると、分散トランザクションに昇格するという厄介な習慣があります。System.Transactions Integration with SQL Server (ADO.NET) を参照してください。分散トランザクションには、クライアントがコミットされて切断された後でも持続するという厄介な特性があります。SQL Server が実際に「永久に」コミットする前に、トランザクション コーディネーターによって承認される必要があります。このような状態で検査すると2 ( )sys.dm_tran_active_transactionsと表示されます。これが事実であることが判明した場合、さらに調査するには、MSDTC のトラブルシューティングが必要になります。dtc_statePREPARED

最後に、注意事項があります。単純な SELECT がロックを保持するのはなぜですか? 有害なデフォルト コンストラクタ フォームnew TransactionScope()を使用していますか? これはデフォルトの SERIALIZABLE 分離レベルを使用しますが、これは 99% 過剰であり、実際には有害です。明示的な使用を試してTransactionOptions、分離レベルを に設定してくださいReadCommitted

于 2012-07-12T15:09:49.840 に答える