Мое приложение не выполняет резервное копирование сообщений — IBM MQ

#java #jms #ibm-mq #message-queue

#java #jms #ibm-mq #очередь сообщений

Вопрос:

Я пишу приложение springboot, которое использует JmsListener для чтения сообщений из очереди, и я хочу отменить их, если возникнет исключение во время отсоединения очереди. Поэтому всякий раз, когда в мой InputQueue добавляется новое сообщение, прослушиватель анализирует сообщение и заполняет объект. Через MQExplorer я настроил свои 2 очереди, одна из которых имеет пороговое значение ‘1’, поэтому после одного пинг-понга сообщения оно доставляется в очередь BO. Конечно, в основной очереди настроена соответствующая очередь BO через панель «память». Я думаю, что код написан правильно, но что-то не работает должным образом. После отладки я вижу, что исключения правильно генерируются и перехватываются, но @Transactional не помещает сообщение в очередь возврата, даже если происходит откат. Я также пытался использовать другую очередь, но результат тот же. Вот некоторые из моих классов:

     @SpringBootApplication
    @RestController
    @Configuration
    @EnableJms
    @EnableAutoConfiguration
    @EnableTransactionManagement
    @EnableJpaRepositories
    @EntityScan
    public class myApplication{

   public static void main(String[] args) {
      SpringApplication.run(myApplication.class, args);
  }

    }
  

     @Component
    public class MyListenerXML{
@JmsListener(destination = "inputQUeue")
public void receiveMessage(Message message) throws Exception, Throwable {
try {
            // My instructions
            //This must be transactional  
             doTransaction();
            //This does not need to be transactional 
            foo(); 
} catch (JmsException e) {
        throw e;        
} catch (ReadMessageException e) {
        throw e.getCause();
} catch (JAXBException e) {
        logger.error("Parsing Error!");
        throw e;
} catch (Exception e) {
        logger.error("Error during commit", e.getMessage());
        throw e;
}
}


}




@Transactional(rollbackOn={JAXBException.class,ReadMessageException.class, Exception.class})
public MyEntityObject doTransaction(Message message) throws JAXBException,Exception {
    MyEntityObject myEntityObject = null;
try {
        //My instructions...
        }
} catch (JAXBException e) {
        throw e;
} catch (Exception e) {
        logger.error("Error in the transaction phase!: {}", e.getMessage());
        throw new ReadMessageException(e);
}
    return myEntityObject ;

}
 }


 public String foo (){...}
  

Итак, как вы видите, я использую @Transactional в doTransaction(), поскольку он должен быть атомарным, и если я попытаюсь разорвать входное XML-сообщение, исключения будут правильно сгенерированы. В любом случае транзакции откатываются, но сообщение не попадает в очередь возврата.

Чего мне не хватает?

РЕДАКТИРОВАТЬ: что касается авторизации, у меня нет usr и pwd, но они будут предоставлены позже, поэтому я также настраиваю свойства. Это класс, используемый для определения моей основной очереди.

         @Bean
public MQQueueConnectionFactory connectionFactory() {
    MQQueueConnectionFactory factory = null;
    try {
        factory = new MQQueueConnectionFactory();
        factory.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostname);
        factory.setStringProperty(WMQConstants.WMQ_CONNECTION_NAME_LIST, hostname);
        factory.setIntProperty(WMQConstants.WMQ_PORT, port);
        factory.setStringProperty(WMQConstants.WMQ_CHANNEL, channel);
        factory.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
        factory.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManager);
        factory.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, userAuthMQCSP);
        factory.setStringProperty(WMQConstants.USERID, user);
        factory.setStringProperty(WMQConstants.PASSWORD, password);
        factory.createConnection(user, password);
    } catch (JMSException e) {
        logger.error("Error in MQ defintion"   e.getMessage());
    }
    return factory;
}

  @Bean
public JmsTemplate jmsTemplate() {
    return new JmsTemplate(connectionFactory());
}

   @Bean
  public JmsListenerContainerFactory jmsListenerContainerFactory() {
      DefaultJmsListenerContainerFactory factory =
              new DefaultJmsListenerContainerFactory();
      factory.setConnectionFactory(connectionFactory());
      return factory;
  }
  

Комментарии:

1. Возможно, я неправильно читаю это, но ваше описание предполагает, что порог возврата установлен в очереди возврата, а не в основной очереди приложений? Для того, чтобы классы JMS использовали пороговое значение возврата, номер должен быть установлен в основной очереди приложений.

2. Нет, резервное копирование установлено в основной очереди приложений. @MoragHughson

3. Можете ли вы обновить вопрос, указав определение основной очереди и разрешение OAM, которое вы предоставили пользователю для очереди BO и диспетчера очередей?

4. обновлен вопрос @JoshMc.

5. Можете ли вы предоставить мне вопросы, связанные с конфигурацией диспетчера очередей?