Сообщение jms не постоянная повторная доставка после остановки запуска appServer

Используйте очередь 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.

Я хочу избежать повторного получения сообщения.

Это возможно (и как)?

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);
}

Вы можете сделать его короче, используя преимущества API:

public void asynchWatched(Pdv pdv, boolean pending) {
   jmsContext.createProducer()
     .setDeliveryMode(DeliveryMode.NON_PERSISTENT);
     .send(csPdvQueue, pdv);
}
Другие вопросы по тегам