WebSphere MQ wmq.jmsra在MDB中的异常之后循环

时间:2015-05-22 10:50:36

标签: 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标头中找到超出退出阈值的退出计数。

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

约克

1 个答案:

答案 0 :(得分:0)

我们已经找到了强制适配器被强制循环的原因。由于错误输入我们的boq配置错误,max-msg-len属性比引用队列小8倍。如果有一条消息比boq的max-msg-len大,并且异常强制它移动到boq,则ressource-adapter试图将它放到boq并失败。通常情况下,ressouce-adapter应该将其移动到dlq,但由于丢失了事务,这也失败了。在无法移动到dlq之后,ressource-adapter没有丢弃该消息,但它再次尝试将其移动到boq,这再次失败并且循环已经启动。

在我看来,ressource-adapter的行为并不是真的正确,但如果同步max-msg-len属性,问题不应该发生。

感谢Umapathy的支持。

约克