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?

Author: Ben ODay, 2014-02-13

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;
 0
Author: Ben ODay, 2014-02-13 04:14:30