与jms确认模式相关的混淆

时间:2014-07-17 14:28:01

标签: jms

我有一个多个使用者正在侦听队列,当一个消息到达时,它的onMessage()函数被调用。由于有多个消费者,每个消费者都有自己的会话。要求是只有在没有问题且没有抛出异常的情况下才应该确认消息......)

AUTO_ACK模式:我的理解是:onMessage成功完成后确认消息。如果onMessage()中存在异常,则将重新传递该消息。 客户端确认:在onMessage()结束时,我显式调用了acknowledge()。如果出现错误,将不会调用acknowledge()方法,因此将重新传递消息。 事务会话:我在onMessage()函数的末尾调用session.commit(),如果遇到一些异常,我会捕获它并调用session.rollback,因此将重新传递消息。

消费者可以检测重复的消息并适当地处理它。我的问题是,所有3种模式都在做同样的事情并解决了我的目的,那么哪种方法比另一种更好,为什么呢?简而言之,为什么我应该通过客户端确认或自动模式使用事务处理会话。 我不想使用JTA / XA,因为它不受所有jms提供程序示例activeMQ的支持,它会使我的应用程序变慢。

如果我的消费者无法处理重复的消息,那么我理解我唯一的选择是使用JTA / XA,因为所有其他选项都可以再次向我发送消息,这将导致重复处理。在JTA / XA中,我也可以再次获取该消息,但不会将其视为重复处理,因为之前的事务将被回滚。

1 个答案:

答案 0 :(得分:1)

这里要小心ack模式之间的区别,因为它们可能比你想象的更微妙。

当使用自动确认并在onMessage中抛出异常时,您的消息可能会重新传送到另一个客户端,同一客户端,或者根据您的代理及其配置方式进入DLQ。

许多人忽略了客户确认的事实是客户端确实正在执行为父会话传递的所有先前消息,因此如果您在同一会话中有多个消费者,那么您的确认也可以通知您的消息呼叫。因为在你的情况下你每个会话都有一个消费者,所以你会回到auto ack的情况,消息将被重新传递或者可能会转到DLQ。

在本地事务情况下,在重新分配给其他消费者或路由到DLQ之前,消息通常会根据客户端或代理配置重新传递给同一客户端多次。

在某种程度上,您选择的模式取决于您对多个故障结果的期望,以及如何配置您选择的Broker实现来处理它。