来自Oracle AQ Java消费者连接的频繁SQLNet中断错误

时间:2014-02-13 00:08:13

标签: java oracle jms oracle-aq

我们的DBA注意到很多SQLNet中断错误归因于Oracle AQ Java进程的连接导致这些队列耗尽。我没有在Java方面看到任何错误,否则它似乎工作正常。我们的方法有什么可以导致这些休息吗?

这是来自数据库端的错误...使用Oracle版本11.2.0.3

ORA 25228
25228, 00000, "timeout or end-of-fetch during message dequeue from %s.%s"
// *Cause: User-specified dequeue wait time has passed or the end of the
//         queue has been reached but no message has been retrieved.
// *Action: Try dequeue again with the appropriate WAIT_TIME or the
//          FIRST_MESSAGE option.

这是我们如何初始化Java AQ连接/会话......

private static Queue queue = null;

public void init() { 
  QueueConnectionFactory queueConnectionFactory = AQjmsFactory.getQueueConnectionFactory(server, schema,    1521, "thin");
  QueueConnection queueConnection = queueConnectionFactory.createQueueConnection(user, password);
  queueConnection.start();
  QueueSession queueSession = queueConnection.createQueueSession(true, Session.CLIENT_ACKNOWLEDGE);
  queue = ((AQjmsSession )queueSession).getQueue(streamUser, streamQueue);
 }

然后使用计时器(每15秒),我们定期调用此块来排空队列......

QueueReceiver qr = queueSession.createReceiver(queue);

while (true) {
  Message message = qr.receive(1000);
  if(message == null) {
    break;
  } else {
    //process the msg
    queueSession.commit();
  }
}

我还看了一下使用onMessage()异步回调方法,但出于各种原因我们更喜欢这种方法......

问题#1

虽然这是Oracle AQ文档中引用的一个示例,但它看起来是一种非常简单的方法,是否有更稳定的方式将消息在Java中出列?

问题#2

另外,我想知道CLIENT_ACK模式是否可能是罪魁祸首...我应该明确地调用message.acknowledge()还是queueSession.commit()覆盖这个?

1 个答案:

答案 0 :(得分:0)

经过一些研究,这听起来像是Oracle AQ出队的一个错误,只要队列为空就会被抛出

参考:

然后应该被捕获并被忽略,如下:

   ...
   EXCEPTION
      WHEN OTHERS
      THEN
         IF SQLCODE = -25228 /* Timeout; queue is likely empty... */
         THEN
            item := NULL;
         ELSE  
            RAISE;
         END IF;