エンキューとデキューにOracleODP.Netを使用しています。
プロセスA:エンキュープロセスB:MessageAvailableイベントでデキュー
プロセスAとBが実行されている場合、問題はありません。「プロセスB」では、イベントは常に発生します。
ただし、「プロセスB」がオフで「プロセスA」がオンの場合、「プロセスB」を再起動すると、オフ時間中に挿入されたキューは失われます。
過去に挿入されたすべてのキューに対してイベントを発生させるオプションはありますか?
どうもありがとう
この問題に対処するには、次の 2 つのアプローチがあるようです。
私はこのトピックについて頭を悩ませてきました。新しいメッセージを「手動で」テストする必要がある場合、そもそも MessageAvaiable イベント コールバックを使用する利点は何ですか? 私が熟考した 1 つのルートは、(メッセージが受信されるかタイムアウトが発生するまで) 呼び出し元がスレッドでブロックされないように、非同期呼び出しで Listen() メソッドをラップすることです。カスタム Receive() メソッドで Listen() と Dequeue() をラップし、独自の MessageReceived イベント ハンドラーを作成して、メッセージの詳細を呼び出し元のスレッドに渡しました。ODP.NETはすぐに使用できるコールバックを提供するため、多少冗長に思えますが、説明した問題に対処する必要はありません(または、「孤立した」メッセージを「手動で」テストするコードを記述します.
アプローチに関するコメント/考えは大歓迎です。
私もこれを見ていて、グレッグに似たようなことをしてしまいました. 私は Listen() メソッドを使用していませんが、単純な Dequeue() 以上のものを提供するとは思わないため、Listen() は、複数のコンシューマーに代わってリッスンする場合に役立つようです。私のインスタンスは関係ありません ( Oracle Docsを参照)。
したがって、私の「プロセス B」では、既存のメッセージを確認するためにポーリング プロセスを開始する前に、最初に通知を登録します。Listen() ではなく、数秒の Wait 期間が設定された制御ループ内で Dequeue() を呼び出すだけです。ポーリング プロセスで Oracle タイムアウトが発生すると、待機期間が終了し、ポーリングが停止します。待機期間が満了していない場合は、タイムアウトの処理を検討する必要があるかもしれません (ただし、これが発生する可能性があるかどうかは 100% 確実ではありません)。
ポーリング中にエンキューされたメッセージはメッセージ通知メソッドを呼び出しますが、これが接続してメッセージを取得しようとするまでに、ポーリングプロセスは常にそれを取得しているように見えます。したがって、メッセージ通知メソッド内で、番号が 25263 の OracleExceptions をキャプチャして無視します ( no message in queue <...> with message ID <...>
)。