Я пишу приложение 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;
}