6.6. 健壮的消息应用

可以将消息的传送模式设置为持久性或非持久性;此模式控制消息传送的可靠性。

QueueSender 接口:

send(Message message, int deliveryMode, int priority, long timeToLive)

TopicPublisher接口:

publish(Message message, int deliveryMode, int priority, long timeToLive)

其中deliveryMode可以为以下两个值。

DeliveryMode.NON_PERSISTENT
DeliveryMode.PERSISTENT

保证只将持久性消息传送成功。在消息服务发生故障时,持久性消息不会丢失。

在消息服务发生故障时,非持久性消息可能会丢失。

对于持久性消息,确保可靠性有两个方面。

确认

生成消息时,消息服务器确认它已收到传送的消息,将该消息置于其目标中并进行持久性存储。生产者的 send() 方法会阻塞,直至确认返回为止。

使用消息时,客户机确认已收到从某个目标传送来的消息并已使用,然后消息服务器中删除该消息。

本地事务

可以将session事务属性配置为true,这样,可以将一个或多个消息的生成和/或使用组成原子单元,也就是事务。JMS API 提供了启动、提交或回滚事务的方法。

createSession(boolean transacted,int acknowledgeMode)

在事务中生成或使用消息时,消息服务跟踪各个发送和接收过程,并在 JMS 客户机发出提交事务的调用时完成这些操作。如果事务中特定的发送或接收操作失败,则出现异常。客户机代码通过忽略异常、重试操作或回滚整个事务来处理异常。在事务提交时,将完成其所有操作。在事务进行回滚时,将取消所有成功的操作。

分布式事务

AMQ 还支持分布式事务。也就是说,消息的生成和使用可作为较大的分布式事务的一部分,该分布式事务中包括涉及其他资源管理器(如数据库系统)的操作。在分布式事务中,分布式事务管理器使用 Java 事务 API (JTA)、XA 资源 API 规范中定义的两阶段提交协议,跟踪和管理由多个资源管理器(如消息服务和数据库管理器)执行的操作。

支持分布式事务是指消息传送客户机可通过 JTA 定义的 XAResource 接口参与分布式事务。此接口定义了实现两阶段提交的许多方法。当客户机端进行 API 调用时,JMS 消息服务只与分布式事务管理器(由 Java 事务服务 (JTS) 提供)协作来跟踪分布式事务中的各种发送和接收操作、事务状态并完成消息传送操作。

长期订阅

消息服务器还可以持久性地存储长期订阅消息。否则,当消息服务器发生故障时,就无法向长期订户传送消息;消息到达主题目标后,长期订户会恢复活动状态。

要保证成功传送消息,消息传送应用程序必须将消息指定为持久性消息,并将它们传送给具有长期订阅的主题目标或传送给队列目标。

public Retailer( String broker, String username, String password){
    try {
        ...
        hotDealsTopic = (Topic)jndi.lookup("Hot Deals");
        javax.jms.TopicSubscriber subscriber =
        session.createDurableSubscriber(hotDealsTopic, "Hot Deals Subscription");
        subscriber.setMessageListener(this);
        connect.start( );
        ....
}