Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么JMS要两次传递消息?_Jms - Fatal编程技术网

为什么JMS要两次传递消息?

为什么JMS要两次传递消息?,jms,Jms,我正在使用JMS执行一些长时间运行的导入过程,但是遇到了一些我不太理解的重复消息问题 流程如下。一些支持bean代码向消息bean发送消息。消息bean接收此消息,轮询第三方服务,然后如果有新数据要导入,则将这些行提交到数据库中。问题是,在导入过程需要一些时间(大约60秒)的情况下,JMS会发送我的消息两次。如果没有要导入的新行,并且该过程大约需要30秒,则消息只发送一次 我认为这与消息接收的确认有关,所以我做的第一件事(因为自动确认不起作用)是将QueueSession设置为Session.C

我正在使用JMS执行一些长时间运行的导入过程,但是遇到了一些我不太理解的重复消息问题

流程如下。一些支持bean代码向消息bean发送消息。消息bean接收此消息,轮询第三方服务,然后如果有新数据要导入,则将这些行提交到数据库中。问题是,在导入过程需要一些时间(大约60秒)的情况下,JMS会发送我的消息两次。如果没有要导入的新行,并且该过程大约需要30秒,则消息只发送一次

我认为这与消息接收的确认有关,所以我做的第一件事(因为自动确认不起作用)是将QueueSession设置为Session.CLIENT_acknowledge,并将msg.acknowledge()放在我的onMessage方法中。不幸的是,这些信息仍被发送了两次

在此过程中,不会引发任何错误代码或异常

这是密码

豆荚

public MyBackingBean(){
    try {
        InitialContext ctx = new InitialContext();
        qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
        qcon = qconFactory.createQueueConnection();
        qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

        queue = (javax.jms.Queue) ctx.lookup(IMPORT_QUEUE);
        qsender = qsession.createSender(queue);
        qsender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        qcon.start();

    } catch (JMSException e) {
        System.out.println(e);
    } catch (NamingException e) {
        System.out.println(e);
    }

public void startImport() {
        try {
            // send a JMS message for the long running job
            MapMessage mapMessage = qsession.createMapMessage();
            mapMessage.setObjectProperty("ipAddress", "127.0.0.1");
            qsender.send(mapMessage);
        } catch (JMSException e) {
            e.printStackTrace();
        } catch (Throwable te) {
            te.printStackTrace();
        }
}
在导入消息Bean中

@Override
public void onMessage(Message msg) {
    try {
           // create an ADF Application Module
           // poll a third party for some data
           // copy these rows (if new) and then 
           // commit via the ADF Application Module
        }
    catch (Exception e){
       // no errors are being thrown
    }
}

现在,我不检查复制,看看这个消息是不是重发(MSG.GETJMSReIDELVIEW()),而忽略了副本,但是我不太喜欢创可贴。< /P>


有人对此有什么建议吗?

威尔,我不能确定发生了什么,但要知道,使用AUTO_ACKNOWLEDGE,直到线程从onMessage()调用返回,确认才真正发生。因此,如果您在onMessage()调用中花费60秒,我对重新交付并不感到惊讶。 使用CLIENT_ACKNOWLEDGE,通过调用msg.ACKNOWLEDGE(),您应该明确地确认消息。然而,你是在什么时候这样做的?在onMessage()中花费60秒之后?我想你也会有同样的行为。 您可以在输入onMessage()调用后立即调用msg.acknowledge(),但要意识到这意味着,如果您的onMessage()方法稍后发生崩溃,消息将无法重新传递。但看起来您并没有使用持续交付,所以您可能不在乎

这里有一个很好的参考