Можем ли мы использовать многопоточность в PL / SQL? - PullRequest
24 голосов
/ 23 февраля 2009

Есть ли какая-либо особенность асинхронного вызова в PL / SQL? Предположим, что я нахожусь в блоке кода, хотел бы вызвать процедуру несколько раз и не беспокоиться, когда и что процедура возвращает?

BEGIN
  myProc(1,100);
  myProc(101,200);
  myProc(201,300);
  ...
  ...

END;

В приведенном выше случае я не хочу, чтобы мой код ожидал, пока myProc (1100) завершит обработку, прежде чем выполнить (101,200)
Спасибо.

Ответы [ 9 ]

24 голосов
/ 23 февраля 2009

+ 1 для подходов DBMS_SCHEDULER и DBMS_JOB, но также подумайте, следует ли вам использовать другой подход.

Если у вас есть процедура, которая выполняется построчно, и вы обнаружите, что она медленная, ответ, вероятно, состоит не в том, чтобы запускать процедуру несколько раз одновременно, а в том, чтобы вместо нее использовать подход на основе множеств , В крайнем случае вы даже можете использовать параллельный запрос и параллельный DML для сокращения времени настенного времени процесса.

Я упоминаю об этом только потому, что это очень распространенная ошибка.

17 голосов
/ 23 февраля 2009

Отправьте в 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, чтобы порождать потоки для обработки заданий. Вы можете запросить работу, изучив представление user_jobs.

Обратите внимание, что это относится к Oracle 9i, но не уверен, что поддержка 10g имеет. Подробнее здесь .

РЕДАКТИРОВАТЬ: добавлен пропущенный COMMIT

11 голосов
/ 23 февраля 2009

Возможно, вы захотите заглянуть в DBMS_SCHEDULER.

Отредактировано для полноты:

DMBS_SCHEDULER доступен в Oracle 10g. Для версий до этого DBMS_JOB выполняет примерно ту же работу.

Для получения дополнительной информации см .: http://download.oracle.com/docs/cd/B12037_01/server.101/b10739/jobtosched.htm

10 голосов
/ 09 января 2011

Для параллельной обработки PL / SQL у вас есть следующие опции:

Это позволит вам "эмулировать" разветвление и многопоточность в PL / SQL. Конечно, используя их, вы можете понять необходимость взаимодействия между параллельно выполняемыми процедурами. Для этого проверьте:

Лично я реализовал систему параллельной обработки с использованием DBMS_Scheduler и использовал DBMS_Pipe для связи между «потоками». Я был очень доволен сочетанием этих двух факторов, и моя главная цель (сократить время обработки с помощью особой тяжелой процедуры) была достигнута!

5 голосов
/ 03 ноября 2011

У вас есть еще один вариант, начиная с 11g. Oracle представила пакет, который делает нечто похожее на то, что вы хотите сделать, с именем DBMS_PARALLEL_EXECUTE

Согласно им, «пакет DBMS_PARALLEL_EXECUTE позволяет пользователю постепенно обновлять данные таблицы параллельно». Довольно хорошее описание того, как его использовать: здесь

По сути, вы определяете способ, которым Oracle должен использовать, чтобы разбить вашу работу на части (в вашем случае вы, кажется, передаете какое-то ключевое значение), а затем он запустит каждую из частей по отдельности. Конечно, для его использования требуется немного планирования и немного дополнительного кодирования, но ничего такого, чего вы не должны были делать в любом случае.

Преимущество использования санкционированного метода, такого как этот, заключается в том, что Oracle даже предоставляет представления базы данных, которые можно использовать для мониторинга каждого из независимых потоков.

5 голосов
/ 23 февраля 2009

Другой способ сделать параллельный (многопоточный) PL / SQL показан здесь:

http://www.williamrobertson.net/documents/parallel-plsql-launcher.html

Недостатком использования dbms_job или dbms_schedular является то, что вы не знаете, когда ваши задачи завершены. Я читал, что вы не беспокоитесь, но, возможно, вы передумаете в будущем.

РЕДАКТИРОВАТЬ:

Эта статья http://www.devx.com/dbzone/10MinuteSolution/20902/0/page/1 описывает другой путь. Он использует dbms_job и dbms_alert. Предупреждения используются, чтобы сигнализировать, что работы выполнены (сигнал обратного вызова).

1 голос
/ 14 сентября 2011

Параллельный конвейерный подход, перечисленный здесь AskTom, обеспечивает более сложный подход, но вы фактически остановитесь, пока работа не будет завершена, в отличие от методов работы СУБД. Тем не менее, вы запросили «асинхронную» технику, и DBMS_JOB идеально подходит для этого.

1 голос
/ 23 февраля 2009

Вот объяснение различных способов выгрузки данных в плоский файл. Один из способов показывает, как можно ускорить параллельное выполнение с PL / SQL.

http://www.oracle -developer.net / display.php? ID = 425

0 голосов
/ 03 июля 2009

Рассматривали ли вы использование Oracle Advaned Queuing?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...