erreurs fréquentes de rupture SQLNet des connexions grand public Oracle AQ Java
Notre DBA a remarqué beaucoup d'erreurs de rupture SQLNet attribuées aux connexions effectuées à partir de processus Java Oracle AQ qui drainent ces files d'attente. Je ne vois aucune erreur du côté Java et cela semble bien fonctionner sinon. Y a-t-il quelque chose dans notre approche qui provoquerait ces ruptures?
Voici l'erreur du côté DB...utilisation d'Oracle version 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.
Voici comment nous initialisons notre connexion/session 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);
}
Puis avec une minuterie (toutes les 15s), on appelez périodiquement ce bloc pour vider la file d'attente...
QueueReceiver qr = queueSession.createReceiver(queue);
while (true) {
Message message = qr.receive(1000);
if(message == null) {
break;
} else {
//process the msg
queueSession.commit();
}
}
J'ai également examiné l'utilisation de l'approche de rappel asynchrone onMessage (), mais nous avons préféré cette approche pour diverses raisons...
Question # 1
Bien que ce soit un exemple référencé dans la documentation AQ d'Oracle et que cela semble être une approche assez simple, existe-t-il un moyen plus stable de supprimer les messages en Java?
Question # 2
De plus, je me demande si le mode CLIENT_ACK pourrait être le coupable...dois-je appeler explicitement message.acknowledge()
ou le queueSession.commit()
couvre-t-il cela?
1 answers
Après quelques recherches, cela ressemble à un bogue dans la file d'attente d'Oracle AQ et est lancé chaque fois qu'une file d'attente est vide
Références:
Qui devrait alors être juste attrapé et ignoré, comme ceci:
...
EXCEPTION
WHEN OTHERS
THEN
IF SQLCODE = -25228 /* Timeout; queue is likely empty... */
THEN
item := NULL;
ELSE
RAISE;
END IF;