Можем ли мы использовать потоки в PL/SQL?
Есть ли какая-либо функция асинхронного вызова в PL/SQL?
Предположим, что я в блоке кода хотел бы вызвать процедуру несколько раз и не стал бы беспокоиться о том, когда и что возвращает процедура?
BEGIN
myProc(1,100);
myProc(101,200);
myProc(201,300);
...
...
END;
В приведенном выше случае я не хочу, чтобы мой код дождался, когда myProc (1,100) завершит обработку перед выполнением (101,200)
Спасибо.
Ответы
Ответ 1
+1 для подстановок DBMS_SCHEDULER и DBMS_JOB, но также подумайте над тем, следует ли использовать другой подход.
Если у вас есть процедура, которая выполняется в строке за строкой, и вы обнаружите, что она медленная, ответ, вероятно, заключается не в том, чтобы запускать процедуру несколько раз одновременно, а для того, чтобы вместо этого использовать aproach на основе набора, В крайнем случае вы можете даже использовать параллельный запрос и параллельный DML для уменьшения времени настенных часов процесса.
Я упоминаю об этом только потому, что это очень распространенная ошибка.
Ответ 2
Отправить в DBMS_JOB следующим образом:
declare
ln_dummy number;
begin
DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(1,100); end;');
DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(101,200); end;');
DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(201,300); end;');
COMMIT;
end;
Вам понадобится параметр job_queue_processes, установленный в > 0, для создания потоков для обработки заданий. Вы можете запросить задания, просмотрев view user_jobs.
Обратите внимание, что это относится к Oracle 9i, не уверен, что такое поддержка 10g. Подробнее см. здесь.
EDIT: добавлен пропущенный COMMIT
Ответ 3
Вы можете посмотреть в DBMS_SCHEDULER.
Отредактировано для полноты:
DMBS_SCHEDULER доступен на Oracle 10g. Для версий до этого DBMS_JOB выполняет примерно ту же работу.
Для получения дополнительной информации см. http://download.oracle.com/docs/cd/B12037_01/server.101/b10739/jobtosched.htm
Ответ 4
Для параллельной обработки PL/SQL у вас есть следующие параметры:
Они позволят вам "эмулировать" разветвление и потоки в PL/SQL. Конечно, используя их, вы можете осознать необходимость общения между параллельными выполняемыми процедурами. Для этого проверьте:
Лично я реализовал систему параллельной обработки, используя DBMS_Scheduler, и использовал DBMS_Pipe для связи между "потоками". Я был очень доволен сочетанием этих двух, и моя главная цель (сократить время обработки с помощью специальной тяжелой процедуры) была достигнута!
Ответ 5
Здесь показан другой способ выполнения параллельных (многопоточных) PL/SQL:
http://www.williamrobertson.net/documents/parallel-plsql-launcher.html
Недостатком использования dbms_job или dbms_schedular является то, что вы действительно не знаете, когда ваши задачи завершены. Я читал, что вы не беспокоитесь, но, возможно, вы измените свое мнение в будущем.
EDIT:
Эта статья http://www.devx.com/dbzone/10MinuteSolution/20902/0/page/1 описывает другой способ. Он использует dbms_job
и dbms_alert
. Сигналы используются для оповещения о выполнении заданий (сигнал обратного вызова).
Ответ 6
У вас есть еще один вариант, начиная с 11g. Oracle представила пакет, который делает что-то похожее на то, что вы хотите сделать, с именем DBMS_PARALLEL_EXECUTE
По их словам, "пакет DBMS_PARALLEL_EXECUTE позволяет пользователю постепенно обновлять данные таблицы параллельно". Хорошее резюме о том, как его использовать, здесь
В основном вы определяете способ, которым Oracle должен использовать, чтобы разбить вашу работу на части (в вашем случае вы, кажется, передаете некоторое ключевое значение), а затем он начнет каждую из частей отдельно. Конечно, немного планирования и немного дополнительного кодирования, чтобы использовать его, но ничего, что вы не должны делать в любом случае.
Преимущество использования санкционированного метода, например, заключается в том, что Oracle даже предоставляет представления базы данных, которые могут использоваться для мониторинга каждого из независимых потоков.
Ответ 7
Вот объяснение различных способов разгрузки данных в плоский файл. Один из способов показывает, как вы можете выполнять параллельное выполнение с PL/SQL, чтобы ускорить процесс.
http://www.oracle-developer.net/display.php?id=425
Ответ 8
Параллельный конвейерный подход, указанный здесь askTom, обеспечивает более сложный подход, но вы фактически приостанавливаете работу до завершения работы, в отличие от методов работы СУБД. Тем не менее, вы просили "асинхронную" технику, и DBMS_JOB идеально подходит для этого.
Ответ 9
Рассматривали ли вы использование Oracle Advaned Queuing?