Мое приложение не возвращает сообщения - IBM MQ - PullRequest
0 голосов
/ 20 апреля 2019

Я пишу приложение Springboot, которое использует JmsListener для чтения сообщений из очереди, и я хочу отменить их, если произойдет исключение во время отключения очереди. Таким образом, всякий раз, когда новое сообщение добавляется в мой inputQueue, слушатель анализирует сообщение и заполняет сущность. Через MQExplorer я настроил свои 2 очереди, у BO есть порог «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;
  }
...