Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > JMS: одноразовая, 100% доставка Соощения


Автор: LeoGL 3.10.2012, 18:32
Доброго времени суток.

Третий день копаюсь в JMS. Прочитал не один туториал, спецификацию, побегал по форумам, но внятного ответа на свой вопрос так и не нашёл.

Как известно, jms работает следующими образом:

Продюсер посылает сообщение (вне трансакции), сервер принимает его и подтверждает, после чего send разблокируется. Теперь представим, что во время этой процедуры обрывается соединение клиент-сервер. А произойти это может, когда

- сообщение летит на сервер (т.е. не достигает его)
- подтверждение летит к клиенту (клиент не получил подтверждение, но сообщение лежит на сервере)

В обоих случаях, клиент поучает JMSException, что сигнализирует об ошибки.
Так вот, вопрос: Как различить эти две ситуации? Как и что для этот следует настроить? Послать сообщение ещё раз может привести к двухразовой его обработки. Не послать его вовсе - тоже не выход. 

Гарантирует ли jms одноразовой, 100% доставки сообщения?

Автор: jk1 3.10.2012, 20:20
Цитата

Гарантирует ли jms одноразовой, 100% доставки сообщения? 


 “Полную гарантию может дать только страховой полис”  (с)  О. Бендер

А если серьезно, то в тонкостях этих ситуаций разбираться незачем. Снабдите свои сообщения уникальным идентификатором.
Если producer получил JMSException при отправке, то он просто перепосылает сообщение. Consumer в свою очередь должен игнорировать сообщения, id которых он уже видел.

Автор: COVD 3.10.2012, 20:27
Не знаю, как эта проблема решается в JMS (интересно было бы узнать). Но никак, кроме использования уникального номера сообщения, на мой взгляд невозможно. Отправитель должен знать последний номер, подтвержденный получателем. Получатель должен знать последний обработанный им номер. Я не уверен, что эти вопросы синхронизации потока сообщений, возникающие при подключениях, входят в сферу ответственности JMS. Скорее, это ответственность приложений - отправителя и получателя. 

Автор: Stolzen 4.10.2012, 10:12
Если я правильно понял, то речь идет о шаблоне http://www.eaipatterns.com/TransactionalClient.html

Пример из книги EIP:

Код

Connection connection = // Get the connection
Session session = 
    connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
Queue queue = // Get the queue
MessageConsumer consumer = session.createConsumer(queue);
Message message = consumer.receive();
session.commit();


Автор: LeoGL 4.10.2012, 15:20
Вот что говорит спецификация (4.4.13 Duplicate Production of Messages) по этому поводу:

If a failure occurs between the time a client commits its work on a Session and the commit method returns, the client cannot determine if the transaction was committed or rolled back. The same ambiguity exists when a failure occurs between the non-transactional send of a PERSISTENT message and the return from the sending method.

It is up to a JMS application to deal with this ambiguity. In some cases, this may cause a client to produce functionally duplicate messages.
A message that is redelivered due to session recovery is not considered a duplicate message.

То бишь, отправитель не в состоянии различить эти две ситуации...

Всем спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)