JMS排队场景所需的建议

时间:2012-10-16 20:19:18

标签: java jms activemq

JMS排队方案所需的建议

嗨,我是Java EE和应用服务器的新手,我想知道JMS队列(或ActiveMQ?)解决方案是否适用于我的场景。现在我想不是,但似乎有很多我可能不知道的选择。

我有客户端应用程序可以访问项目(数据库上的数据),并将锁定该项目,直到客户端完成。如果他没有关闭应用程序,客户端可能会锁定项目很多天。

我需要开发一个Web服务,该服务将发布到要在项目上完成的队列操作。 困难的部分是,如果此项目当前处于锁定状态,则需要暂停这些操作。(我不知道该锁何时被释放;所以我需要有一个计时器,将试图使这些行动出局。)

因此,如果项目A当前被锁定,那么我的队列 可能看起来像这样:

  1. 将数据XXX添加到项目 A
  2. 将数据ZZZ添加到项目B
  3. 更新项目的数据XXX A
  4. 更新项目B的数据ZZZ
  5. 删除项目B的数据ZZZ
  6. 如果 A 被锁定,我需要能够继续处理B(或任何其他未锁定项目)上的操作,并在其锁定被释放后稍后处理项目A.

    我考虑过为每个项目创建内存JMS队列,这些队列具有待处理操作以保留其顺序)但我不能(也不应该)因为队列是由App Server定义的。我显然需要持久队列(所以没有临时队列?)

    JMS是否为这种情况排队正确? ActiveMQ或其他实现可以帮助吗?

    我是否必须在Timer上使用自己的Queue / SQL Table / EJB进行编码?

1 个答案:

答案 0 :(得分:0)

JMS和其他方法都有很多选择。

但这是我对JMS(ActiveMQ或其他)的一种可能解决方案的想法:

你可以有一个用于输入消息的JMS队列和一个用于保留消息的队列(等待在某个锁定的项目上处理)。希望你也有一些ID(我称之为“projectId”,以识别一个锁定的项目)。我还假设您可以在项目发布时执行代码。

以下是一些psudecode,您可以在使用队列实现此方案时如何思考。

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); 
   }
}