java - WebSphere MQ wmq.jmsra 在 MDB 中出现异常后循环

标签 java jboss transactions ibm-mq jboss-mdb

我在使用 JBoss EAP 6 和 WebSphere MQ 时遇到问题。我开发了一个消息驱动的 bean:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/VGT.EXTERN.IN"),
    @ActivationConfigProperty(propertyName = "clientID", propertyValue = "VGT_BYSENDINGSYSTEMDISPATCHERMDB") })
@Pool(value = "BySendingSystemDispatcherMDB-pool")
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class BySendingSystemDispatcherMDB implements javax.jms.MessageListener {

private Logger logger = Logger.getLogger(getClass());

@Inject
@Named
BySendingSystemDispatcher bySendingSystemDispatcher;

@Resource
MessageDrivenContext mdc;

@Inject
@Named
Listener listener;

@Override
public void onMessage(Message message) {
    try {
        // Weiterbearbeitung deligieren
        bySendingSystemDispatcher.onMessage(message);
    } catch (JMSException e) {
        listener.handleExceptionWhenMessageIsPoisend(e);
        logger.error(e.getLinkedException(), e);
        mdc.setRollbackOnly();
    } catch (JAXBException e) {
        mdc.setRollbackOnly();
        listener.handleExceptionWhileProcessingMessage(message, e);
        logger.error(e.getMessage(), e);
    } catch (ClassCastException e) {
        logger.error(e.getMessage(), e);
        mdc.setRollbackOnly();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        mdc.setRollbackOnly();
    } finally {
        // logging
        if (logger.isDebugEnabled()) {
            String id = null;
            try {
                id = message.getJMSMessageID();
                logger.debug(((TextMessage) message).getText());
            } catch (Exception e) {
                logger.debug("logging of message - " + id + " failed");
            }
        }

    }

}

bySendingSystemDispatcher.onMessage(message) 方法抛出一个源自 java.lang.Exception 的异常,并用 @ApplicationException(rollback=true) 进行注释。如果发生这种情况,消息将按照配置重新传递 5 次,之后它会在资源适配器中循环,并且不会再传递。我已经使用 HornetQ 检查了相同的场景,它按预期工作。

MQ将抛出以下异常

Class : class javax.jms.JMSException
Stack : com.ibm.msg.client.commonservices.trace.Trace.ffst(Trace.java:1611)
      : com.ibm.msg.client.wmq.common.internal.messages.WMQSendMarshal.constructMQMD(WMQSendMarshal.java:287)
      : com.ibm.msg.client.wmq.common.internal.messages.WMQSendMarshal.exportMQMDAndMessageBuffers(WMQSendMarshal.java:503)
      : com.ibm.msg.client.wmq.common.internal.messages.WMQSendMarshal.exportMQMD(WMQSendMarshal.java:567)
      : com.ibm.msg.client.wmq.internal.WMQPoison$PoisonMessage.calculateMqmdAndBuffers(WMQPoison.java:1816)
      : com.ibm.msg.client.wmq.

一个有趣的点是,您可以在 MQMD header 中找到超过回退阈值的回退计数。

知道发生了什么以及如何解决吗?

约尔格

最佳答案

我们找到了资源适配器被迫循环的原因。由于输入错误,我们的 boq 配置错误,max-msg-len 属性比引用队列小 8 倍。如果有一条消息大于 boq 的 max-msg-len,并且异常迫使其移动到 boq,则资源适配器会尝试将其放入 boq,但会失败。通常,资源适配器应该将其移动到 dlq,但这也失败了,因为事务丢失。移动到 dlq 失败后,资源适配器没有丢弃该消息,而是再次尝试将其移动到 boq,但再次失败并开始循环。

在我看来,资源适配器的行为并不真正正确,但如果同步 max-msg-len 属性,则不会出现问题。

感谢 Umapathy 的支持。

约尔格

关于java - WebSphere MQ wmq.jmsra 在 MDB 中出现异常后循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30394792/

相关文章:

具有后端功能的 Java Web 服务

php - 处理现实世界中的交易

spring - 事务在junit中不起作用?

java - 应用程序仅在 Samsung Galaxy S7 Edge 上速度缓慢并出现 OutOfMemoryException

java - 如果任何模块中存在模拟实例,则在创建 RoboGuice 注入(inject)器期间进程崩溃

java - hibernate 5 java.lang.NoSuchMethodError org.jboss.logging.Logger.debugf

django - 在表单内应用事务原子是否正确?

java - 为什么 IntelliJ IDEA 不会创建没有带有 Main() 方法的类的 JAR 工件?

java - 如何使用流、Map<String, Object> 按包含键的 List<String> 进行过滤

java - JDK1.8.0_92无法编译JSP文件