1

エンキューとデキューにOracleODP.Netを使用しています。

プロセスA:エンキュープロセスB:MessageAvailableイベントでデキュー

プロセスAとBが実行されている場合、問題はありません。「プロセスB」では、イベントは常に発生します。

ただし、「プロセスB」がオフで「プロセスA」がオンの場合、「プロセスB」を再起動すると、オフ時間中に挿入されたキューは失われます。

過去に挿入されたすべてのキューに対してイベントを発生させるオプションはありますか?

どうもありがとう

4

2 に答える 2

5

この問題に対処するには、次の 2 つのアプローチがあるようです。

  1. OracleAQQueue クラスの Listen() メソッドを(メッセージ通知の登録後に)コールして、キューにある孤立したメッセージを取得します。Listen() は、メッセージが受信されるかタイムアウトが発生するまでブロックされることに注意してください。そのため、メッセージがキューにない場合に処理スレッドに戻る (短い) タイムアウトを指定する必要があります。
  2. Dequeue() メソッドを呼び出して、Oracle エラー 25228 (デキューできるメッセージがありません) をトラップします。Oracle サポート フォーラムの次のスレッドを参照してください: https://forums.oracle.com/forums/thread.jspa?threadID=2186496

私はこのトピックについて頭を悩ませてきました。新しいメッセージを「手動で」テストする必要がある場合、そもそも MessageAvaiable イベント コールバックを使用する利点は何ですか? 私が熟考した 1 つのルートは、(メッセージが受信されるかタイムアウトが発生するまで) 呼び出し元がスレッドでブロックされないように、非同期呼び出しで Listen() メソッドをラップすることです。カスタム Receive() メソッドで Listen() と Dequeue() をラップし、独自の MessageReceived イベント ハンドラーを作成して、メッセージの詳細を呼び出し元のスレッドに渡しました。ODP.NETはすぐに使用できるコールバックを提供するため、多少冗長に思えますが、説明した問題に対処する必要はありません(または、「孤立した」メッセージを「手動で」テストするコードを記述します.

アプローチに関するコメント/考えは大歓迎です。

于 2012-06-20T03:38:23.703 に答える
0

私もこれを見ていて、グレッグに似たようなことをしてしまいました. 私は Listen() メソッドを使用していませんが、単純な Dequeue() 以上のものを提供するとは思わないため、Listen() は、複数のコンシューマーに代わってリッスンする場合に役立つようです。私のインスタンスは関係ありません ( Oracle Docsを参照)。

したがって、私の「プロセス B」では、既存のメッセージを確認するためにポーリング プロセスを開始する前に、最初に通知を登録します。Listen() ではなく、数秒の Wait 期間が設定された制御ループ内で Dequeue() を呼び出すだけです。ポーリング プロセスで Oracle タイムアウトが発生すると、待機期間が終了し、ポーリングが停止します。待機期間が満了していない場合は、タイムアウトの処理を検討する必要があるかもしれません (ただし、これが発生する可能性があるかどうかは 100% 確実ではありません)。

ポーリング中にエンキューされたメッセージはメッセージ通知メソッドを呼び出しますが、これが接続してメッセージを取得しようとするまでに、ポーリングプロセスは常にそれを取得しているように見えます。したがって、メッセージ通知メソッド内で、番号が 25263 の OracleExceptions をキャプチャして無視します ( no message in queue <...> with message ID <...>)。

于 2012-11-19T12:13:52.337 に答える