#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. Можете ли вы предоставить мне вопросы, связанные с конфигурацией диспетчера очередей?