我们的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()
覆盖这个?
答案 0 :(得分:0)
参考:
然后应该被捕获并被忽略,如下:
...
EXCEPTION
WHEN OTHERS
THEN
IF SQLCODE = -25228 /* Timeout; queue is likely empty... */
THEN
item := NULL;
ELSE
RAISE;
END IF;