0

使用 jms 队列。

ejb发件人:

@Resource(lookup = "jms/csPdvQueue")
private Queue csPdvQueue;
@Inject
private JMSContext jmsContext;

方法发送消息:

public void asynchWatched(Pdv pdv, boolean pending) {
   jmsContext.createProducer().setDeliveryMode(DeliveryMode.NON_PERSISTENT);
   jmsContext.createProducer().send(csPdvQueue, pdv);
}

ejb消费者:

@MessageDriven(mappedName = "jms/csPdvQueue")
public class PdvProcessorMdb implements MessageListener {

    @Override
    public void onMessage(Message message) {
    ... execute some businesslogic...
    }

}

如果应用程序服务器(payara)在消息消费(onMessage)期间退出,则事务正确回滚。

当应用程序服务器再次启动时,即使我设置了 DeliveryMode.NON_PERSISTENT,消息也会重新传递。

我想避免重新发送消息。

有可能(以及如何)?

4

1 回答 1

1

发送消息时,您这样做setDeliveryMode(DeliveryMode.NON_PERSISTENT);,这意味着消息不会在消息代理重新启动之间保存。如果您在嵌入式模式下使用 OpenMQ 代理(默认),它将与服务器一起重新启动。因此重启后,消息不存在,无法再次发送。

更新:

但是,您的代码在不同于发送消息的生产者上设置了传递模式(创建了一个生产者,设置了传递模式,然后丢弃;下一行创建一个新的生产者,它发送消息)。您需要将创建的生产者存储在一个变量中,设置交付方式,然后使用相同的生产者发送消息:

public void asynchWatched(Pdv pdv, boolean pending) {
   JMSProducer producer = jmsContext.createProducer();
   producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
   producer.send(csPdvQueue, pdv);
}

您可以利用 fluent API 来缩短它:

public void asynchWatched(Pdv pdv, boolean pending) {
   jmsContext.createProducer()
     .setDeliveryMode(DeliveryMode.NON_PERSISTENT);
     .send(csPdvQueue, pdv);
}
于 2017-02-09T23:09:01.340 回答