为什么JMS要两次传递消息?
我正在使用JMS执行一些长时间运行的导入过程,但是遇到了一些我不太理解的重复消息问题 流程如下。一些支持bean代码向消息bean发送消息。消息bean接收此消息,轮询第三方服务,然后如果有新数据要导入,则将这些行提交到数据库中。问题是,在导入过程需要一些时间(大约60秒)的情况下,JMS会发送我的消息两次。如果没有要导入的新行,并且该过程大约需要30秒,则消息只发送一次 我认为这与消息接收的确认有关,所以我做的第一件事(因为自动确认不起作用)是将QueueSession设置为Session.CLIENT_acknowledge,并将msg.acknowledge()放在我的onMessage方法中。不幸的是,这些信息仍被发送了两次 在此过程中,不会引发任何错误代码或异常 这是密码 豆荚为什么JMS要两次传递消息?,jms,Jms,我正在使用JMS执行一些长时间运行的导入过程,但是遇到了一些我不太理解的重复消息问题 流程如下。一些支持bean代码向消息bean发送消息。消息bean接收此消息,轮询第三方服务,然后如果有新数据要导入,则将这些行提交到数据库中。问题是,在导入过程需要一些时间(大约60秒)的情况下,JMS会发送我的消息两次。如果没有要导入的新行,并且该过程大约需要30秒,则消息只发送一次 我认为这与消息接收的确认有关,所以我做的第一件事(因为自动确认不起作用)是将QueueSession设置为Session.C
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()方法稍后发生崩溃,消息将无法重新传递。但看起来您并没有使用持续交付,所以您可能不在乎 这里有一个很好的参考