2017-02-09 7 views
0

использовать jms queue.jms message non persistent redelivery after stop-start appServer

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... 
    } 

} 

если сервер приложений (скумбриевидный гидролик) завершает работу во время сообщения потребляя (OnMessage), то транзакция корректно откат.

Когда сервер приложений запускается снова, сообщение повторно добавляется, даже если я установил DeliveryMode.NON_PERSISTENT.

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

Возможно ли (и как)?

+0

«при запуске приложения. Такое же сообщение получает от потребителя, но отправитель ничего не отправляет». - Не могли бы вы лучше объяснить? Как вы можете получить от потребителя - потребитель не отправляет сообщение, а получает его. Получает ли оно одно и то же сообщение после перезапуска или нет? – OndrejM

ответ

1

При отправке сообщения вы делаете setDeliveryMode(DeliveryMode.NON_PERSISTENT);, что означает, что сообщение не будет сохранено между перезапусками брокера сообщений. Если вы используете брокер OpenMQ во встроенном режиме (по умолчанию), он будет перезапущен вместе с сервером. Поэтому после перезагрузки сообщение не существует и не может быть отправлено повторно.

Update:

Однако ваш код устанавливает режим доставки на другой производитель, чем который один посылает сообщение (производитель создан, установлен режим доставки, а затем выбрасываются, следующая строка создает новый производитель, который отправляет сообщение). Вы должны сохранить созданный производителем в переменной, установите режим доставки, а затем использовать один и тот же производитель, чтобы отправить сообщение:

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

Использование встроенного брокера сообщений. С кодом, отправленным на почту, asynchWatched send message -> onMessage receive message -> Во время сообщения процесса остановите сервер -> Restart server -> onMessage получите сообщение. – omarbr

+0

Спасибо за объяснение. Теперь я понял, что вы * хотите, чтобы сообщение не было доставлено снова. Поэтому вы правильно хотите установить режим доставки NON_PERSISTENT. Но код устанавливает его на другого производителя. Вы должны сохранить созданного производителя, установить на нем режим доставки, а затем отправить сообщение с использованием того же производителя. См. Мой обновленный ответ. – OndrejM

+0

очевидно работает. Прошу прощения за мою тупую ошибку! – omarbr