1

Oracle DB からレコードを取得して MySql DB に挿入する C# のサービスが 1 つあります。MySql DB にすべてのレコードを正常に挿入した後、Oracle DB の列の 1 つが更新されます。つまり、これらの多くのレコードが挿入されます。

サービスであるため、5秒ごとに呼び出されます。

私の問題は、この場合のデッドロック状況をどのように処理すればよいかということです。私のサービスが Oracle DB から約 20,000 レコードを取得し、約 7 ~ 8 秒かかる MySql DB に挿入しようとしているように、サービスが呼び出される間、前のセッションのすべてのレコードが挿入されていないため、 Oracle DBで更新すると、次回はレコード全体が再びフェッチされますが、これは望ましくありません。

可能であれば、同じコードも提供してください。これは、WCF ではなく純粋な Window ベース サービスです。

4

4 に答える 4

0

機能要件が何であるかはわかりませんが、前の実行が完了するまで、サービスでの処理を実際に開始したくないようです。つまり、既存の実行が進行中であるかどうかを確認し、次のプロセスを開始する前にこれを確認するための何らかのシステムが必要です。もう1つのオプションは、リクエストをキューに入れてから、それらをバッチとして処理し、重複を効果的に削除することです。

于 2012-08-21T12:06:47.307 に答える
0

Oracleへの挿入が完了するのを待つ必要があるようです。したがって、リクエストをc#でキューに入れます。つまり、同期的に行います。Mutexオブジェクトの使用を検討してください。

于 2012-08-21T12:07:10.000 に答える
0

このサービスでのみ「調整」が必要な場合は、AutoResetEventクラスを使用します。

  1. AutoResetEventインスタンスで静的フィールドを作成します。
  2. タイマーによって呼び出されるメソッドは、開始時にAutoResetEvent.WaitOne(TimeSpan timeout)呼び出しを介してこのインスタンスをチェックする必要があります。
  3. メソッドの最後(タイマーによって呼び出される)で、常にAutoResetEvent.Set()を呼び出します。通常、 try{} finally{}の構築はこの呼び出しに問題ありません。
  4. サービスの開始時に、作成されたインスタンスのAutoResetEvent.Set()を呼び出して、メソッド (タイマーによって呼び出される) が動作を開始できるようにします。

小さなタイムアウトでWaitOne(TimeSpan タイムアウト)を使用すると、前のタイマーがまだ終了していない場合に、タイマーの「呼び出し」をすばやく終了できます。したがって、5 秒ごとにメソッドを呼び出すことができます。

そのメソッドを呼び出す前に、AutoResetEvent の破棄について確実に確認する必要があります。

于 2012-08-21T12:50:37.627 に答える
0

ここにはいくつかのオプションがあると思います。

  1. 本当に必要でない場合は特に、サービスを頻繁に実行しないでください。あなたは、5 秒ごとに 20,000 レコードを取得するサービスがあると言っています。
  2. すべての読み取り操作が待機するように、更新が完了するまで Oracle テーブルにロックを発行します。
  3. タイマーではなくイベントでサービス デリゲートを起動しないでください。そのため、最初にサービスを開始したときは手動でイベントを発生させますが、その後発生したイベントはすべて、更新の完了後に発生します。

個人的には、オプション #3 を好みます。

于 2012-08-21T12:08:55.353 に答える