0

我们的 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()覆盖这个?

4

1 回答 1

0

经过一些研究,这听起来像是 Oracle AQ 出队中的一个错误,并且每当队列为空时都会抛出

参考:

然后应该抓住并忽略它,如下所示:

   ...
   EXCEPTION
      WHEN OTHERS
      THEN
         IF SQLCODE = -25228 /* Timeout; queue is likely empty... */
         THEN
            item := NULL;
         ELSE  
            RAISE;
         END IF;
于 2014-02-13T04:14:30.417 回答