如何从主题中删除邮件

我正在尝试编写一个使用JMS发布订阅模型的应用程序。 但是我遇到了挫折,我希望能够让发布者从主题中删除消息。 用例是我拥有持久的订阅者,活跃的订阅者将获得消息(因为它或多或少立即),但如果有非活动订阅者并且发布者决定消息错误,我想让他能够删除消息这样订阅者一旦活跃就不会再收到它了。 问题是,我不知道如何做到这一点。 对于提供商,我决定使用glassfish的实现,但如果其他替代方案提供此function,我可以切换。

谢谢。

JMS是一种异步消息传递forms,因此发布者和订阅者在设计上是分离的。 这意味着没有机制可以满足您的要求。 对于在发布时处于活动状态的订阅者,他们将使用该消息而不能及时接收删除消息以对其进行操作。 如果订阅者处于脱机状态,那么他们会,但异步消息应该是primefaces的。 如果您继续设计其他响应者的答案(创建删除消息并要求重新连接消费者以读取整个队列以查找删除消息),那么您将创建一种情况,其中系统的行为根据订户是否不同而不同在发布特定消息/删除组合时是否在线。 还存在竞争条件,其中订户在发布者发出删除消息之前完成对保留消息的读取。 这意味着您必须将重要逻辑放入订阅者以协调这些条件,甚至更多地协调竞争条件。

可以接受的方法就是所谓的“补偿交易”。 在生产者和消费者不共享单个工作单元或共享公共状态(例如使用相同的DB来存储状态)的任何系统中,退出或纠正先前的事务需要第二个事务来反转第一个事务。 消费者当然必须能够正确地应用补偿交易。 使用此模式时,结果是所有订阅者都表现出相同的行为,无论消息是在消费者重新启动后实时消耗还是批量消费。

请注意,补偿交易与“删除消息”不同。 其他响应者的答案中提出的删除消息是一种影响消息流本身的命令和控制forms。 另一方面,补偿事务通过系统状态的事务更新来影响系统的状态。

作为一般规则,您永远不想通过使用命令和控制function操纵消息流来管理系统状态。 这很脆弱,容易受到攻击,很难进行审计或调试。 相反,设计系统以提供受其服务质量约束的每条消息并处理所有消息。 完全在应用程序中处理状态更改(包括撤消先前操作)。

例如,在交易触发次要影响(如透支费用)的银行业务中,常见的程序是在白天“备忘录”交易,然后在银行关闭后批量分类并应用它们。 这允许导致透支费用之前协调错误。 最近,这些交易是实时应用的,但触发器被扣留,直到当天的账簿结束,这样才能达到相同的效果。

JMS API不允许从任何目标(队列或主题)中删除邮件。 虽然我相信特定的JMX提供商提供他们自己的专有工具来管理他们的状态,例如使用JMX。 尝试检查一下您的JMS提供程序,但要小心:即使您找到解决方案,它也无法在不同的JMS提供程序之间移植。

“删除”消息的一种合法方式是使用其生存时间: publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive) 。 可能它对你来说已经足够了。

如果它不适用于您的应用程序,请解决应用程序级别的问题。 例如,为每条消息附加唯一ID,并发布具有更高优先级的特殊“删除”消息,这将是一种删除具有相同ID的“真实”消息的命令。

您已让生产者发送delete消息,并且消费者需要在开始处理之前阅读所有消息。