Spring 如何实现JMS侦听器来忽略基于列表/映射的特定消息?

Spring 如何实现JMS侦听器来忽略基于列表/映射的特定消息?,spring,jms,activemq,Spring,Jms,Activemq,我将表示两个用户之间的操作的消息发送到队列。 用户作为属性存储在消息上。 当同时处理涉及一个或另一个用户的不同操作时,要求不允许[从队列中]处理操作 因为我使用的是Grails(意思是Spring)和ActiveMQ,所以我考虑以这种方式实现它: 创建一个带有事务的MessageListenerContainer,当侦听器读取该消息时,它将获得事务的状态,检查userA或userB当前是否有已处理的操作,并根据结果处理该操作或回滚jms事务。 我考虑创建一个简单的地图来存储当前处理用户的详细信息

我将表示两个用户之间的操作的消息发送到队列。 用户作为属性存储在消息上。 当同时处理涉及一个或另一个用户的不同操作时,要求不允许[从队列中]处理操作

因为我使用的是Grails(意思是Spring)和ActiveMQ,所以我考虑以这种方式实现它:

创建一个带有事务的MessageListenerContainer,当侦听器读取该消息时,它将获得事务的状态,检查userA或userB当前是否有已处理的操作,并根据结果处理该操作或回滚jms事务。 我考虑创建一个简单的地图来存储当前处理用户的详细信息:

{
  userId : [listenerId, timestamp]
}
我想存储侦听器id和时间戳,这样就有了一种简化错误处理的方法[还没有实现]

所以,在处理操作之前,用户ID将放在那个里,而在操作完成之后,密钥将被删除

不幸的是,我在原型设计时遇到了一个大问题。当我回滚消息时,侦听器将等待并再次读取相同的消息。 这意味着,如果我为userA获得了5个操作,并且只有5个侦听器,那么当处理第一个操作时,整个过程都将被卡住。那不是我想要的。 我希望听者阅读一条消息,检查是否可以处理操作,如果不能,则阅读下一条消息。 甚至可以实施吗

在我的一个监听器原型中,当我发送5条消息并回滚它们时,我得到的是[这是从reader获得的:读取消息时的时间戳+消息编号]:

1288892171570 0
1288892171578 0
1288892176582 0
1288892181586 0
1288892186589 0
1288892191594 0
1288892196596 0
1288892201601 1
1288892206604 1
1288892211607 1
1288892216612 1
1288892221614 1
1288892226618 1
1288892231621 1
1288892236625 2
1288892241629 2
1288892246632 2
1288892251636 2
1288892256641 2
1288892261645 2
1288892266647 2
1288892271652 3
1288892276656 3
1288892281659 3
1288892286663 3
1288892291667 3
1288892296671 3
1288892301674 3
1288892306679 4
1288892311682 4
1288892316686 4
1288892321689 4
1288892326693 4
1288892331696 4
1288892336700 4
重新交付策略是AMQ 5.4.1的默认策略。 我想看到的是: 0,1,2,3,4,0,1,2,3,4,0,1,2,3,4

我认为它应该在某种程度上起作用,当事务回滚并且消息被标记为重新交付时,它将被延迟,但侦听器将继续工作。此外,当消息重新传递时,它将返回到队列中的位置-队列按消息时间戳排序

示例[假设所有5条消息同时发送]: 读取消息0,执行检查,可处理->处理 读取消息1,执行检查,无法处理,事务回滚,延迟X时间 读取消息2,执行检查,无法处理,事务回滚,延迟X时间 读取消息3,执行检查,无法处理,事务回滚,延迟X时间 消息1在经过X个时间段后重新交付,执行检查,无法处理,事务回滚,延迟X个时间段 Msg 4已读取

我不确定我尝试做的是明智的,还是应该考虑以其他方式做?我认为这种方式将是简单和易于扩展的。 也许这只是AMQ配置的问题,但我确实查看了,但在“重新交付”设置中没有找到任何有帮助的内容

谢谢, Krystian

这似乎是活动MQ的一个“功能”: 撰写本文时的问题正在等待审查,但其中包含一个链接,该链接指向一个可以使用Camel实现的解决方案。 我认为这是我将要走的路[至少现在是这样]。 我将创建两个队列: actionsQueue 忙碌的队列

侦听器将从actionsQueue执行操作,并测试是否可以处理某个操作。 如果没有,它会将消息发送到busyQueue。 我将让camel在busyQueue上监听消息,并以配置的延迟自动将消息路由到actionsque

如果我想用最初的想法实现它,这似乎是前进的方向

我仍然想知道是否有更好的方法来做到这一点