Jakarta ee 有人确切地知道,如果客户端崩溃,哪些JMS消息将在客户端确认模式下重新传递吗?
该规范说“确认一条已消费的消息自动确认其会话已发送的所有消息的接收”——但我需要知道的是“已发送”的含义 例如,如果我调用consumer.receive()6次,然后在第三条消息上调用.acknowledge-是(a)只确认前3条消息,还是(b)全部确认6条消息 我真的希望这是选项a,也就是说,在你调用acknowledge之后的消息将被重新传递,否则在我有机会坚持并确认消息之前,很难看到你如何防止在我的接收方进程崩溃时丢失消息。但是规范的措辞并不清楚。我得到的印象是,JMS规范的作者考虑了代理失败,但没有花太多时间考虑如何防止客户端失败:o( 谢谢Jakarta ee 有人确切地知道,如果客户端崩溃,哪些JMS消息将在客户端确认模式下重新传递吗?,jakarta-ee,jms,Jakarta Ee,Jms,该规范说“确认一条已消费的消息自动确认其会话已发送的所有消息的接收”——但我需要知道的是“已发送”的含义 例如,如果我调用consumer.receive()6次,然后在第三条消息上调用.acknowledge-是(a)只确认前3条消息,还是(b)全部确认6条消息 我真的希望这是选项a,也就是说,在你调用acknowledge之后的消息将被重新传递,否则在我有机会坚持并确认消息之前,很难看到你如何防止在我的接收方进程崩溃时丢失消息。但是规范的措辞并不清楚。我得到的印象是,JMS规范的作者考虑了代
Ben根据规范,选项(b)是正确的行为。如果您获得选项(a)并依赖它,则应用程序将无法移植 在下面的解释中,我具体指的是JMS规范版本1.1(2002年4月12日) 当确认方法实际上在会话级别上运行时,从消息对象调用确认方法这一事实会造成一些混乱。因为它是一种消息方法,直观地说,可以在消息流中选择一个点来生成确认,这似乎是正确的 但真正发生的是,消息确认在会话级别驱动提交调用。由于会话一次只能有一个事务处于活动状态,因此每个确认不限定消息流中的一个点,而是一个时间点。确认提交现有工作单元并启动下一个。消息传递ack之前的ed必须包含在ack提交的工作单元中 “交付”一词通常被认为是API调用的完成,它从队列中删除消息并导致程序内存中的填充对象。实际上,消息被认为是在从队列中移除时传递的,而不管它是否对程序产生影响。例如,考虑以下事件序列:
在您的示例中,您“调用consumer.receive()6次,然后在第3条消息上调用.acknowledge”,并观察到消息4到6已重新传递,可能的解释是a)这六条消息并非都来自同一会话,或者b)行为不符合规范。谢谢,这非常有用。这不是我所希望的答案,但我有一种感觉,可能是这样的。那么,acknowledge方法放在消息对象上而不是会话上是否只是一个意外?正如你所说,它确实给人一种相当误导的印象。我仍然有兴趣知道,除了SonicMQ之外,其他许多提供商是否超越/违反了标准,只承认你调用ack()的消息。。。否则,CLIENT_ACKNOWLEDGE的局限性似乎使它对于真正可靠的消息传递毫无用处。实际上,,是否每个人最终都会使用重量级XA事务,或者放弃一次语义,转而在应用程序层实现可靠性?我怀疑确认方法是在消息上的,因为在这些模型中,会话是容器管理的,并且消息是应用程序唯一可用的对象。无法回答关于其他传输提供程序的问题,因为我对特定提供程序的唯一了解是WebSphere MQ。也许其他人会回应。如果您想吸引更多的评论,请不要忘记接受/投票答案。XA及时确定事务边界的范围,而不是在消息流中的某个点,与客户端确认相同。当调用提交时,XA提交之前传递的任何消息都在同一工作单元中。我不会说CLIENT_ACKNOWLEDGE对于可靠的消息传递是无用的,因为它实现了