2012-04-27 1 views
1

Я использую Oracle ODP.Net для ввода и удаления очереди.Oracle AQ с ODP.Net. Автоматически деактивировать при подключении

Процесс A: Епдиеие Процесс B: Ведиеие с MessageAvailable события

Если процесс А и В работает, нет никаких проблем. В «Процессе B» событие всегда запускается.

Но если «Процесс B» выключен и «Процесс A» включен, когда «Процесс B» перезапускается, очереди, вставленные во время выключения, теряются.

Есть ли возможность запускать событие для всех очередей, вставленных в прошлом?

Большое спасибо

ответ

2

Там, кажется, два подхода к решению этой проблемы:

  1. Вызвать метод Listen() класса OracleAQQueue (после регистрации для получения уведомления о сообщении), чтобы забрать «сиротами» сообщения, сидящие в очереди. Обратите внимание, что Listen() блокируется до тех пор, пока не будет получено сообщение или не произойдет тайм-аут. Поэтому вам нужно указать (короткий) тайм-аут, чтобы вернуться к потоку обработки в случае, если в очереди нет сообщений.
  2. Вызвать метод Dequeue() и уловить ошибку Oracle 25228 (для удаления сообщения не доступно сообщение). См. Следующий раздел на форумах поддержки Oracle: https://forums.oracle.com/forums/thread.jspa?threadID=2186496.

Я почесываю голову на эту тему. Если вам еще нужно «вручную» проверить новые сообщения, в чем преимущество использования обратного вызова события MessageAvaiable в первую очередь? Один из способов, о которых я подумал, заключается в том, чтобы обернуть метод Listen() в асинхронном вызове, чтобы вызывающий объект не блокировал поток (пока сообщение не получено или не произойдет тайм-аут). Я завернул Listen() и Dequeue() в пользовательский метод Receive() и создал собственный обработчик событий MessageReceived для передачи деталей сообщения в вызывающий поток. Кажется, что это несколько избыточно, поскольку ODP.NET обеспечивает обратный вызов из коробки, но мне не нужно разбираться с проблемой, которую вы описываете (или писать код на «вручную» тест для «потерянных» сообщений.

комментарии/мысли о подходе приветствуются.

0

Я тоже смотрел на это тоже и сделал что-то похожее на Грега. Я не использовал метод Listen(), хотя я не думаю, что он предлагает мне ничего более и более простого Dequeue() - Listen() кажется полезным, когда вы хотите слушать от имени нескольких потребителей, что в моем случае не имеет отношения к делу (см. Oracle Docs).

Итак, Процесс B 'Сначала регистрирую для уведомлений перед началом процесса опроса для проверки любых существующих сообщений. Он не выполняет Listen(), он просто вызывает Dequeue() в пределах контролируемого цикла с периодом ожидания на пару секунд. Если процесс опроса встречает тайм-аут Oracle, период ожидания истек, а опрос останавливается. Мне может потребоваться рассмотреть вопрос о тайм-аутах, если период ожидания не истек (хотя не 100% уверен, что это произойдет, если это произойдет).

Я заметил, что любые сообщения, которые находятся в очереди, пока опрос вызовет метод уведомления по сообщениям, но к тому моменту, когда он подключится и пытается получить сообщение, процесс опроса всегда, кажется, взял его. Поэтому внутри метода уведомления сообщения я захватываю и игнорирую любые OracleExceptions с номером 25263 (no message in queue <...> with message ID <...>).

Смежные вопросы