2011-09-11 6 views
3

データベースのデッドロックが発生するWCFサービスがあります。私のサービスでは、審議会に申請書を提出することができます。評議会がそれらを更新できるので、申請書を再度ロードすることもできます。各アプリケーションには、関連する多数のドキュメントがあります。だから、遅いクエリでデッドロックを回避する方法

このようなイベントのセットは一部3で私のサービス

1) Application #1 is submitted 
2) A document is uploaded for application #1 
3) Application #1 is loaded 
4) Part 2 above finishes 

デッドロックに発生した場合、私は理由がパート2での文書からSQLサーバーへの提出にはしばらくかかることであると考えていますWCFサービスを呼び出し、この間にテーブルをロックします。

したがって、データベースアプリケーション#1から読み込んだ場合、関連するドキュメントが問題になります。

私はエンティティフレームワークを使用しています。これをどうすれば解決できますか?私が本当にやりたいのは、完全に提出され、ロックされているテーブルや他のものに実行されないこの状況のドキュメントを読み込むことだけです。これは私が取得しています特定のエラーですちなみに

Message: Transaction (Process ID 93) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

はUPDATE:私は操作の順序を変更することができ、コメントのカップルを持っていました。パート2とパート3がWCFサービスへの別の呼び出しに由来するため、実際にはできません。したがって、操作を注文するのはサービスのユーザー次第です。 「あなたに言いたいことを彼らに教えてもらうように依頼してください。でもそれは簡単ではありません。操作の順序は、実際にブラウザを適切なタイミングで「更新」しているエンドユーザに依存します。

更新#2:この問題の再現方法に関するアドバイスが必要です。私はテストアプリケーションを書いており、上記パート2はパート3での操作をブロックしていますが、結果として、操作3は操作2が終了し、操作3が終了するまでブロックされます。

これは、パート3が通常は3分ではなく1分50分かかることを意味します。なぜそれが私のためにブロックされ、デッドロックを作成しないのでしょうか?私はテストサーバーを使用しているときに見て、そのサーバー上の全体的なデータベーストラフィックの量に関連するか、または一部のデータベース設定がそれに影響を与える可能性がありますか?

1)、トランザクションの終了時にのみsaveChanges()を呼び出して一緒にすべてのクエリを実行する:

答えて

1

は、一般的にデッドロックを回避するために、いくつかの方法(SQL Serverおよびその他のデータベース)があります。

2)は、最初にすべての更新を実行するすべての最後の読み取り(SELECT)とを実行し、データベースの更新を実行する順序を変更します。

3)トランザクションで変更されないデータのトランザクションから読み込みを実行します。

4)アプリケーションロジックを許可する場合、READ UNCOMMITTEDのような無ロックとSERIALIZABLE(パフォーマンスの低下)またはスナップショットまたは他の中間体へのトランザクションの分離レベルを変更します。

5)並列に同一のトランザクションを実行するか、自身をロック二つの異なるトランザクションを実行する二つのスレッドを避けるためlock(lock_object)を使用して同期コードブロックを作成します。

+0

私は質問を更新しました。私は実際に操作の順序を制御することはできません。私の解決策は、あなたの答えのパート4または5に関連していなければなりません。一度にいくつのスレッドも実行できるので、パート5は一種の音ではありません。 – peter

+0

複数のスレッドを実行することはできますが、デッドロックにつながる操作を実行するコードの一部を同期するだけで済みます。これにより、全体的なスループットは低下しますが、別のオプションは、分離レベルを変更してロックを回避することです。 SNAPSHOT分離レベル、SQL Server 2005の新機能ではデッドロックによる問題の解決を試みています。データを変更するときにロックを作成するのではなく、異なるバージョンのデータを格納し、各トランザクションは必要なデータのバージョンを読み取ります。 –

+0

私はあなたの答えが最初だったので、それをチェックしました。私は問題が少し緩和できると思う。デッドロックを引き起こしたクエリは、必要のないフィールド(blob)をデータベースから引き出していました。つまり、クエリからそのフィールドを削除すると、クエリが速くなり、したがってテーブルがロックされているときに発生する可能性が低くなります。実際の問題を解明することは、ブロックする可能性があると確信しているので難しくなりますが、デッドロックの原因となっているものを解決するにはもう少し複雑になります。 – peter

1

ソリューションのカップル:

  • あなたが潜在的にコミットされていない列を有する気にしない場合はREAD UNCOMMITTEDの分離レベルを使用します(これはあなたの状況に依存します)ステップ3に表示されます。より効率的にEFの文脈上の変更

OR

  • バッチと、彼らは(あなたのコードを見ることなく、私はあなたがこれをやってされているかどうかわからない)すべてを一度に実行することを確認してください

EDIT

下記のリンクも、トラブルシューティングに役立つことや、あなたの問題を修正可能性があります

http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx

+0

操作の順序を制御することはできません。私は私の質問を更新しました。私の解決策は私が考える孤立レベルに関連しなければならないだろう。 – peter

関連する問題