Удаление сообщения Non_Persistent из очереди AQ с использованием JMS - PullRequest
1 голос
/ 12 февраля 2020

Я бы хотел удалить из очереди непостоянное (= буферизованное) сообщение JMS из Oracle очереди AQ.

В PL / SQL все в порядке и работает, если я установил

L_DequeueOptions.VISIBILITY    := DBMS_AQ.IMMEDIATE;
L_DequeueOptions.DELIVERY_MODE := DBMS_AQ.BUFFERED;

на дескрипторе.

Параметры энкейера установлены соответственно на IMMEDIATE и BUFFERED.

Тем не менее в Java коде я пытаюсь получить сообщение, используя JMS с javax. jms.QueueReceiver с использованием

QueueReceiver receiver = session.createReceiver(queue, "JMSDeliveryMode = 'PERSISTENT' or JMSDeliveryMode = 'NON_PERSISTENT'");
// and later on:
Message m = receiver.receive(conf.dequeueTimeout);

Я не участвую в транзакции на стороне dequeuer / получателя. Как я могу установить «видимость» в JMS? Любые идеи, почему я не получаю сообщения?

Чего мне не хватает?

Полезная нагрузка - sys.AQ $ _JMS_TEXT_MESSAGE, без сжатия или тому подобное.

btw: the Приложение, снимающее с очереди, работает с использованием постоянных сообщений ...

Обновление: код не работает и для постоянных сообщений, если я использую MessageSelector. Без селектора сообщений и постоянных сообщений это работает!

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

Спецификация JMS (JSR 914) определяет два режима доставки: PERSISTENT и NON_PERSISTENT. Относительно Oracle эти режимы PERSISTENT и BUFFERED.

Однако, похоже, реализация JMS Oracles получает только PERSISTENT по умолчанию.

Сам селектор сообщений проверено реализацией Oracle, но, похоже, не влияет на режим доставки.

Как вы сами указали, QueueReceiver можно преобразовать в AQjmsConsumer для обработки буферизованных сообщений.

AQjmsConsumer consumer = (AQjmsConsumer)session.createReceiver(queue);
consumer.bufferReceive(dequeueTimeout);

То же самое относится и к отправке буферизованных сообщений. Здесь QueueSender должен быть приведен к AQjmsProducer, чтобы иметь под рукой метод для буферизованных сообщений:

AQjmsProducer producer = (AQjmsProducer)session.createProducer(queue);
producer.bufferSend(queue, msg, priority, timeToLive);
1 голос
/ 12 февраля 2020

Мы узнали, как с этим справиться. Непосредственно в JMS нет способа удалить из очереди непостоянные сообщения. Я сомневаюсь, что непостоянное снятие очереди является частью стандарта.

Единственный способ - привести QueueReceiver к oracle.jms.AQjmsConsumer и затем вызвать

      receiver.bufferReceive(timeout);

вместо

      receiver.receive(timeout);

Только отладка в Oracle коде JMS привела нас к этому решению. В Интернете недостаточно документации по этому вопросу.

Кстати: селектор сообщений привел меня в совершенно неправильном направлении.

...