4

我有:

  • hornetq-2.2.14-final 独立服务器
  • 将消息发送到队列 A 的客户端应用程序 C1
  • 使用来自队列 A 的消息的客户端应用程序 C2

C1 使用 jmstemplate 在 CLIENT_ACKNOWLEDGE 模式下发送消息:

<bean name="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" />
    <property name="sessionTransacted" value="true" />
</bean>

所以 C2 应该手动确认消息:

@Override
@Transactional
public void onMessage(Message message) 
{
    try 
    {
        messageHandlerService.handleReceivedMessage(message);
        message.acknowledge();
    } 
    catch (DeserializeXmlException e) 
    {
        // TODO log
        e.printStackTrace();
    }   
    catch (InvalidMessageException e) 
    {
        //TODO log
        e.printStackTrace();
    }
    catch (JMSException e) 
    {
        //TODO log
        e.printStackTrace();
    }   
}

我的问题:

  • 当客户端 C2 收到该消息但在确认之前崩溃时,该消息会发生什么?
  • 有没有超时机制?如果是,确认的默认超时是多少?我该如何修改它?
4

1 回答 1

5

在客户关闭或回滚时,任何未确认的消息都将被发送回队列。

在服务器崩溃的情况下,如果消息不是持久的,则将重新传递消息,就好像什么都没发生一样。

请注意,系统可能会在您调用 ack 时但在 ack 实际到达服务器之前崩溃。

ack 超时是通过改变连接工厂的 callTimeout 来配置的。

请注意,如果您有两个要更新的资源并希望保证 ack 和数据库插入之间的单个提交(或者您接下来要执行的任何操作),那么您需要执行 XA 事务以保证两个分支都将被提交。

该消息将在崩溃后重新发送。如果您需要 100% 的收据保证,您需要 XA。

于 2013-03-06T14:29:58.367 回答