web-dev-qa-db-ja.com

データベースポーリングをメッセージングキューに置き換える

MQからリッスン/読み取り、データベース(ローカルテーブル)にメッセージを永続化するバックグラウンドジョブ(Javaバッチ)があります。次に、トリガーはこのメッセージをWAITINGステータスのキューイングテーブルに送信します。私のポーリングプログラム(Javaではマルチスレッド)は、WAITINGレコードを継続的にポーリングし、それらをピックアップして適切なコンシューマーに送信します(Java program)。また、同じタイプのメッセージを同期的に処理する必要があります(同じ注文番号ですが、両方ともN分に到着します。1つは別の開始前に完了する必要があります)ただし、この場合、データベースのポーリングが原因で、2つのスレッドが同じレコードを取得して問題が発生する可能性があったため、ポーリングを実行しました同期されているため、デッドロックが発生しています。

このデータベースポーリングを削除して、データベースポーリングではなく実行可能なイベントベースのメカニズムまたはキューを利用して、同期を維持する方法を教えてください。

編集-後続のメッセージ処理は、本質的に非同期の4つのタスクで構成されますが、同じタイプ(orderid)の2番目のメッセージを処理する前に、すべてのタスクを完了する必要があります。親プロセスは同期である必要があり、子プロセスは非同期です。同じために2つのキューが必要ですか?

2
Akhil

Kafkaを使用する前にこれを行いました。各レコードを永続化するプログラムを用意し、挿入が成功した後、2番目のキューにメッセージを投稿します。次に、コンシューマーは2番目のキューのメッセージをポーリングして、その作業を実行できます。 MQは、同じキューから読み取る複数のコンシューマーを処理し、順番に処理できる必要があります。

あなたの編集について...それはあなたの親消費者が子供たちにどのようにコミュニケーションするかに依存します。すべてのコンシューマコードが同じJVMにある場合は、2つのキューを使用できます。親コンシューマーはシンクロナイザーとして機能する必要があります。これは、メッセージを順番にプルオフし、子タスクをスレッドとして生成して非同期ビットを実行し、すべての子が完了すると、次の順序をプルできます。子は、コールバックを介して完了ステータスを親に通知できます。または、親が子にスレッド結合を行います。

親と子が別々のJVMで実行されている場合は、別の通信方法を検討する必要があります。この場合。 3番目のキューを使用できます(すべての子がステータスを伝えるために使用します)。親がその機能を持っている場合は、親へのAPIコールバックでもこれを行いました。

どちらの方法でも、親は2番目のキューから別の注文メッセージをプルする前に、すべての完了ステータスを待機する必要があります。また、タイムアウトして、子供たちが予想以上に時間がかかっている場合に警告する方法も必要です。

1
Lajos

MQから読み取るプログラムは、データベースを完全にバイパスして、メッセージを直接コンシューマーにディスパッチすることをお勧めします。最終的には、メッセージをデータベースに挿入して、永続性と履歴を確認することもできます。

または、このプログラムは、メッセージをデータベースに挿入し、消費されるラインIDを使用してイベントをコンシューマープログラムに送信し、同期動作を維持できます。

3
KrapocK