我的 springboot 应用程序正在使用来自 weblogic jms 队列(ReqQueue)的消息,并在处理后将响应发布回另一个队列(RespQueue)。 我最近将weblogic版本从12.2.1.3升级到12.2.1.4。 之后,我面临在 JmsListener 中接收重复消息的问题。
以下是我的配置。
@Bean(name = "myFactory")
public JmsListenerContainerFactory<?> myFactory(
@Qualifier("connectionFactory")
ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setErrorHandler(t -> {
logger.error("Error in listener!", t);
});
// factory.setMessageConverter(jacksonJmsMessageConverter());
factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
factory.setSessionTransacted(true);
factory.setConcurrency("5-13");
configurer.configure(factory, connectionFactory);
logger.error("**** Message AUTO_ACKNOWLEDGE");
return factory;
}
@Autowired
@Bean(name = "connectionFactory")
public JndiObjectFactoryBean connectionFactory(JndiTemplate provider){
JndiObjectFactoryBean factory = new JndiObjectFactoryBean();
factory.setJndiTemplate(provider);
factory.setJndiName(connectionType);
factory.setProxyInterface(ConnectionFactory.class);
return factory;
}
@JmsListener(destination = "jms/ReqQueue", containerFactory = "myFactory")
public void receive(@Payload Message message,
@Header(JmsHeaders.CORRELATION_ID) String correlationId,
@Header(JmsHeaders.MESSAGE_ID) String messageId,
@Headers Map<String, Object> headers,
MessageHeaders messageHeaders,
JmsMessageHeaderAccessor jmsMessageHeaderAccessor) throws JMSException, JmsHeaderValidationException, JsonParseException, JsonMappingException, IOException, InterruptedException
{
weblogic 上的连接工厂设置中的事务超时超过 5 小时。
我在日志中收到此错误:
[WARN] [DefaultMessageListenerContainer-41] [org.springframework.jms.listener.DefaultMessageListenerContainer:895] Setup of JMS message listener invoker failed for destination 'jms/ReqQueue' - trying to recover. Cause: JTA transaction already rolled back (probably due to a timeout)
我还看到一些消息重复传送到侦听器,直到响应成功发布到 RespQueue。但这些消息正在第一次被应用程序成功接收并执行。
如果我在 Weblogic 上将 RespQueue 的消息重新传递限制设置为 0,我可以看到很少有响应没有发布到队列中。
您能帮我解决这个问题吗?谢谢。
编辑:
在调试日志中我发现了这些异常。
[DefaultMessageListenerContainer-28] [org.springframework.transaction.jta.WebLogicJtaTransactionManager:743] Initiating transaction commit
[DEBUG] [DefaultMessageListenerContainer-28] [org.springframework.jms.listener.DefaultMessageListenerContainer:884] Setup of JMS message listener invoker failed - already recovered by other invoker
org.springframework.transaction.UnexpectedRollbackException: JTA transaction already rolled back (probably due to a timeout)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1032)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:251)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076)
at java.lang.Thread.run(Thread.java:750)
我发现在域级别设置的 JTA 事务超时值太低。 将 Home>>domain>>configuration>>JTA>>Timeout 秒的值设置为更高的值后,错误已修复。