2

JMS 排队方案所需的建议

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

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

我需要开发一个 web 服务,该服务将发布到要在项目中完成的队列操作。困难的部分是,如果该项目当前被锁定,则需要暂停这些操作。(而且我不知道何时释放该锁;因此我可能需要一个计时器来尝试使这些操作出列)。

因此,如果项目 A 当前被锁定,我的队列可能如下所示:

  1. 将数据 XXX 添加到项目A
  2. 将数据 ZZZ 添加到项目 B
  3. 更新项目A 的数据 XXX
  4. 更新项目 B 的数据 ZZZ
  5. 删除项目 B 的数据 ZZZ

如果A被锁定,我需要能够继续处理 B(或任何其他未锁定的项目)上的操作,并在项目 A 的锁定被释放时进行处理。

我考虑过在内存中为每个具有挂起操作以保留其顺序的项目创建 JMS 队列)但我不能(也不应该)因为队列将由应用服务器定义。而且我显然需要持久队列(所以没有临时队列?)

JMS 队列是否适合这种情况?ActiveMQ 或其他实现有帮助吗?

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

4

1 回答 1

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); 
   }
}
于 2012-10-16T21:53:04.627 回答