Как остановить удаление сообщений без подтверждения в Oracle AQ?

Я установил Oracle AQ для одного клиента. Я наблюдаю сообщения из этой очереди в веб-приложении Java с режимом CLIENT_ACKNOWLEDGE. Но как только я получаю сообщения в методе onMessage, сообщения, похоже, удаляются из очереди Oracle. Я предполагаю, что сообщение не должно быть удалено, если я не acknowledge его в клиенте. Как мне остановить это?

Схема Oracle Queue выглядит следующим образом:

BEGIN DBMS_AQADM.CREATE_QUEUE_TABLE(
  Queue_table => '"TESTUSER"."myqueuetable"', 
  Queue_payload_type => 'TESTUSER.messageobject', 
  multiple_consumers => false
);
END;
/

BEGIN DBMS_AQADM.CREATE_QUEUE(
  Queue_name => 'TESTUSER.myqueue', 
  Queue_table => 'TESTUSER.myqueuetable', 
  Queue_type => 0, Max_retries => 5, Retry_delay => 0
);
END;
/

BEGIN dbms_aqadm.start_queue (
  queue_name => 'testuser.myqueue'
);
END;

Я наблюдаю за сообщениями в своем Java-приложении, как это

 //somewhere in my app
session = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
queueReceiver = ((AQjmsSession) databaseConnectionManager.getSession())
 .createReceiver(databaseConnectionManager.getQueue(), Messageobject.getORADataFactory());
queueReceiver.setMessageListener(this);


//in my listener class
@Override
public void onMessage(Message message) {
 AdtMessage msg = (AdtMessage) message;

 try {
  Messageobject message = (Messageobject) msg.getAdtPayload();

  if (isUserConnected(message.userId)) {
   logger.debug("Message acknowledged");
   msg.acknowledge();
   //handle the message. the message should be deleted now.
  } else {
   //i don't want the message to be deleted
  }

 } catch (JMSException | IllegalArgumentException | SQLException e) {
  logger.error("An error occurred while sending an outgoing blob", e);
 }
}

person Ramaraj T    schedule 24.02.2020    source источник
comment
Я не знаю Oracle AQ, но согласен, что сообщение не следует удалять. Однако он может попасть в какую-то другую очередь - существует ли в Oracle AQ концепция "очереди недоставленных писем"? Кроме того, я бы рекомендовал изменить вашу процедуру, чтобы использовать транзакционный сеанс .createQueueSession(true,... и откат в случае ошибки. Это должно быть более безопасным и определенно не удалять ваше сообщение.   -  person Axel Podehl    schedule 02.03.2020
comment
откат имеет некоторые нежелательные последствия. Кажется, что сеанс снова получает сообщения, даже если они были доставлены до того, как сеанс был откатан.   -  person Ramaraj T    schedule 03.03.2020
comment
От Oracle очень мало помощи. На данный момент я создал обычную таблицу.   -  person Ramaraj T    schedule 03.03.2020
comment
Вы создаете единую потребительскую очередь, для которой сообщение удаляется, как только оно успешно используется. Чтобы сохранить сообщение, задайте для параметра Retention_time значение больше нуля. См. docs.oracle.com/database/121/ARPLS/d_aqadm. htm#ARPLS109   -  person user1612078    schedule 12.06.2020


Ответы (1)


Вы создаете единую потребительскую очередь, для которой сообщение удаляется, как только оно успешно используется.

Чтобы сохранить сообщение, при создании очереди задайте для параметра reintention_time значение больше нуля.

BEGIN 
  DBMS_AQADM.CREATE_QUEUE(
    Queue_name => 'TESTUSER.myqueue', 
    Queue_table => 'TESTUSER.myqueuetable', 
    Queue_type => 0, Max_retries => 5, Retry_delay => 0,
    retention_time => 300    -- retain for next 5 minutes
  );
END;
/

См. https://docs.oracle.com/database/121/ARPLS/d_aqadm.htm#ARPLS109

person user1612078    schedule 12.06.2020