2

JMSキューイングシナリオに必要なアドバイス

こんにちは。私はJavaEEとアプリケーションサーバーを初めて使用します。JMSキュー(またはActiveMQ?)ソリューションが私のシナリオに適しているかどうかを知りたいです。今はそうではないと思いますが、気づかないかもしれない選択肢がたくさんあるようです。

プロジェクト(データベース上のデータ)にアクセスできるクライアントアプリケーションがあり、クライアントが終了するまでそのプロジェクトをロックします。クライアントがアプリケーションを閉じない場合、クライアントは何日もプロジェクトをロックしている可能性があります。

プロジェクトで実行するキュー操作にポストするWebサービスを開発する必要があります。難しいのは、このプロジェクトが現在ロックされている場合、これらの操作を保留にする必要があることです。(そして、そのロックがいつ解放されるかはわかりません。そのため、これらの操作をデキューしようとするタイマーが必要になる可能性があります)。

したがって、プロジェクトAが現在ロックされている場合、私のキューは次のようになります。

  1. プロジェクトAにデータXXXを追加
  2. プロジェクトBにデータZZZを追加します
  3. プロジェクトAのデータXXXを更新
  4. プロジェクトBのデータZZZを更新
  5. プロジェクトBのデータZZZを削除します

Aがロックされている場合、B(または他のロックされていないプロジェクト)の操作を続行し、後でロックが解除されたときにプロジェクトAを処理できるようにする必要があります。

順序を維持するために保留中の操作があるプロジェクトごとにメモリ内にJMSキューを作成することを考えましたが、キューはApp Serverによって定義されるため、作成できません(作成しないでください)。そして、私は明らかに永続的なキューが必要です(したがって、一時的なキューはありませんか?)

このシナリオでは、JMSキューは適切ですか?ActiveMQまたは別の実装が役立ちますか?

タイマーで独自のキュー/SQLテーブル/EJBでコーディングする必要がありますか?

4

1 に答える 1

0

JMSと他のアプローチの両方について、多くのオプションがあります。

しかし、JMS(ActiveMQなど)を使用した1つの可能な解決策についての私の考えは次のとおりです。

着信メッセージ用のJMSキューと、保留中のメッセージ用の1つのキュー(ロックされたプロジェクトで処理されるのを待機している)を持つことができます。うまくいけば、あなたもいくつかのIDを持っているでしょう(私はそれを「projectId」と呼び、ロックされたプロジェクトを識別します)。また、プロジェクトがリリースされたときにコードを実行できると思います。

キューを使用してこのシナリオを実装する際の考え方を次に示します。

public void onMessage(Message msg){
   ProjData pd = extractProjectData(msg);
   if( projectLocked(pd) ) {
     msg.setStringProperty("projectId",pd.getProjectId());
     sendToOnHoldQueue(pd);
   }else{
    processProjectData(pd);
   }
}

// Say there is an event somewhere when the lock is released
public void onProjectLockReleased(projectId){
   // select messages waiting for this project via Jms selectors..

   // you may or may not want to lock the project here, while working of the "on hold events"
   MessageConsumer consumer = session.createConsumer(onHoldQueue,"projectId='"+projectId+"'");
   while(Messages msg  = consumer.receiveNoWait()){
     processProjectData(pd); 
   }
}
于 2012-10-16T21:53:04.627 に答える