Как правильно закрыть JMS-соединение - PullRequest
0 голосов
/ 24 июня 2018

У меня есть следующий фрагмент кода для опроса моей очереди недоставленных писем в JMS.

Message  m = mconsumer.receive(3000L);
      while (m != null) {
        try {
          sendMessageToDB(m);   
        } catch (DBException ex) {
          writeToDeadLetterQueueBack(m);
        } 
       m = messageConsumer.receive(3000L);
      }

Теперь внутри цикла while, если происходит DBException, мое соединение не закрывается, и если я закрываю соединение внутри блока catch, следующая строка завершится неудачей, так как сессия сейчас закрыта.

m = messageConsumer.receive(3000L);

Как с этим бороться.

1 Ответ

0 голосов
/ 26 июня 2018

Общепринято, что лучше не «записывать» сообщение в очередь недоставленных сообщений, а «откатывать» его обратно, используя транзакционный сеанс.

В вашем проекте вы будете иметь бесконечный цикл постоянного потребления и предварительной публикации сообщений в очереди недоставленных сообщений в случае сбоя БД. Лучше всего отключить эту функцию по таймеру (запускать ежечасно и т. Д.) ... или иметь какую-то логику отключения, чтобы остановить постоянный опрос DLQ во время сценария ошибки.

Общая обработка фиксации и отката одного сеанса за один сеанс с надлежащей процедурой закрытия объекта в блоке finally.

Session session = connection.createSession(true, Session.TRANSACTED);
MessageConsumer consumer = session.createConsumer(session.createQueue('MY.QUEUE.DLQ');

Message  m = mconsumer.receive(3000L);
  while (m != null) {
    try {
      sendMessageToDB(m);
      session.commit();
      m = messageConsumer.receive(3000L);
    } catch (DBException ex) {
      session.rollback();
      logger.error("Rolling back messageId {} due to database error {}", m.getJMSMessageId(), ex);
    } finally {
      if(consumer != null) {
          try { consumer.close(); } catch (JMSException e) { logger.error("Error closing consumer.."); } 
      }
      if(session != null) {
          try { session.close(); } catch (JMSException e) { logger.error("Error closing session.."); } 
      }
      if(connection != null) {
          try { connection.close(); } catch (JMSException e) { logger.error("Error closing connection.."); } 
      }
    }
  }
...