oracle AQ для запланированных работ
У нас есть процесс, который в настоящее время использует Oracle DBMS_SCHEDULER для выполнения. Процесс запускается каждый раз, когда сервер получает данные от внешнего устройства. Планировщик Oracle настроен таким образом, что задание создается при получении внешних данных, задание выполняется немедленно и задание автоматически уничтожается по завершении.
Проблема здесь в том, что несколько устройств могут отправлять данные одновременно. Поскольку процесс включает в себя получение исключительных блокировок в разных точках во время выполнения, иногда одно задание будет переходить на другое, которое уже выполняется (оно отклоняется с помощью ORA-20000).
Я хотел бы как-то использовать механизм Oracle AQ (расширенные очереди) для решения этой проблемы. Я представляю очередь заданий, которые выполняются FIFO. Даже если внешнее устройство B отправляет данные, в то время как процесс в настоящее время обрабатывает данные с внешнего устройства A, очередь предотвращает обработку данных с устройства B до тех пор, пока обработка для устройства A не будет завершена.
Похоже, в документации Oracle нет отдельного раздела об этом типе обработки AQ, но, похоже, это будет довольно распространенный сценарий. Кто-нибудь еще решил этот тип проблемы с Oracle AQ?
1 ответ
Вы можете реализовать это следующим образом: программа заданий планировщика реализована как бесконечная - никогда не сбойный цикл. Этот цикл выводит сообщения из AQ и обрабатывает их. Задание планировщика отправляется только один раз - из системы событий даже запускается AFTER STARTUP ON DATABASE
,
Он не использует ни цепочки планировщика, ни какие-либо другие расширенные опции планировщика. Просто задание планировщика запускается триггером, когда база данных начинает работать, задание "никогда не заканчивается".
Но я думаю, что dbms_scheduler очень мощен в наши дни, и есть способы, как ограничить параллельные выполнения для расписания.
PS: ORA-20000 - это определенный пользователем код ошибки. База данных никогда не возвращает такую ошибку самостоятельно.