25

Is there any feature of asynchronous calling in PL/SQL? Suppose I am in a block of code would like to call a procedure multiple times and wouldn't bother when and what the procedure returns?

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

END;

In the above case, I don't want my code to wait for myProc(1,100) to finish processing before executing(101,200)
Thanks.

Burhan
  • 687
  • 2
  • 8
  • 13

9 Answers9

24

+1 for DBMS_SCHEDULER and DBMS_JOB approaches, but also consider whether you ought to be using a different approach.

If you have a procedure which executes in a row-by-row manner and you find that it is slow, the answer is probably not to run the procedure multiple times simltaneously but to ensure that a set-based aproach is used instead. At an extreme you can even then use parallel query and parallel DML to reduce the wall clock time of the process.

I mention this only because it is a very common fault.

David Aldridge
  • 51,479
  • 8
  • 68
  • 96
  • 3
    Once you let the Parallel hint out-of-the-lab, every Tom, Dick and Harry programmer will put it in every query as if it's a parameter. be vewy, vewy cawfule. –  Feb 23 '09 at 15:58
  • Yes, it will make queries into resource hogs on a busy system. On something like a data warehouse it's quite relevant for ETL code or reports. Using it without a damn good reason on a busy transactional system or operational report on such a system should be grounds for a severe beating. – ConcernedOfTunbridgeWells Jun 26 '09 at 11:08
17

Submit it in a DBMS_JOB like so:

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;

You'll need the job_queue_processes parameter set to >0 to spawn threads to process the jobs. You can query the jobs by examining the view user_jobs.

Note that this applies to Oracle 9i, not sure what support 10g has. See more info here.

EDIT: Added missed COMMIT

darreljnz
  • 2,300
  • 2
  • 18
  • 18
  • 2
    For information, DBMS_JOB was deprecated in Oracle 10g by DBMS_SCHEDULER. Please see http://download.oracle.com/docs/cd/B12037_01/server.101/b10739/jobtosched.htm – Matthew Farwell Feb 23 '09 at 12:19
  • 1
    One trick with this is that you need to COMMIT before the jobs will actually start running. I've seen this missed by a few people. – WW. Feb 24 '09 at 01:41
11

You may want to look into DBMS_SCHEDULER.

Edited for completeness:

DMBS_SCHEDULER is available on Oracle 10g. For versions before this, DBMS_JOB does approximately the same job.

For more information, see: http://download.oracle.com/docs/cd/B12037_01/server.101/b10739/jobtosched.htm

Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
10

For PL/SQL Parallel processing you have the following options:

These will let you "emulate" forking and threading in PL/SQL. Of course, using these, you may realize the need to communicate between parallel executed procedures. To do so check out:

Personally I've implemented a parallel processing system using DBMS_Scheduler, and used DBMS_Pipe to communicate between "threads". I was very happy with the combination of the two, and my main goal (to reduce major processing times with a particular heavy-weight procedure) was achieved!

frohiky
  • 371
  • 3
  • 9
6

You do have another option starting in 11g. Oracle has introduced a package that does something similar to what you want to do, named DBMS_PARALLEL_EXECUTE

According to them, "The DBMS_PARALLEL_EXECUTE package enables the user to incrementally update table data in parallel". A fairly good summary of how to use it is here

Basically, you define a way that Oracle should use to break your job up into pieces (in your case by you seem to be passing some key value), and then it will start each of the pieces individually. There is certainly a little planning and a little extra coding involved in order to use it, but nothing that you shouldn't have been doing anyways.

The advantage of using a sanctioned method such as this is that Oracle even provides database views that can be used to monitor each of the independent threads.

Dwayne King
  • 829
  • 1
  • 7
  • 15
5

Another way of doing parallel (multi-threaded) PL/SQL is shown here:

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

The disadvantage of using dbms_job or dbms_schedular is that you don't really know when your tasks are finished. I read that you don't bother but maybe you will change your mind in the future.

EDIT:

This article http://www.devx.com/dbzone/10MinuteSolution/20902/0/page/1 describes another way. It uses dbms_job and dbms_alert. The alerts are used to signal that the jobs are done (callback signal).

APC
  • 144,005
  • 19
  • 170
  • 281
tuinstoel
  • 7,248
  • 27
  • 27
  • 1
    With DBMS_Scheduler you can easily wrap the call to execute a scheduler chain in a procedure that will check for completion of the chain steps, and return to the calling procedure on completion or failure of the chain. – David Aldridge Apr 03 '13 at 11:07
1

Here an explanation of different ways of unloading data to a flat file. One of the ways shows how you can do parallel execution with PL/SQL to speed things up.

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

tuinstoel
  • 7,248
  • 27
  • 27
1

The parallel pipelined approach listed here by askTom provides a more complex approach, but you will actually pause until the work is complete, unlike the DBMS Job techniques. That said, you did ask for the "asynchronous" technique, and DBMS_JOB is perfect for that.

-1

Have you considered using Oracle Advaned Queuing?