job VS Scheduler, Oracle 10G - oracle

Is there someone who can strictly give me what is the job (DBMS_JOB) and the scheduler (DBMS_SCHEDULER) in oracle? and what's its roles ?
Regards.

At first glance it looks like only other names with more human readable schedules for dbms_scheduler, compared to dbms_job. When looking slightly better, there are loads of differences, even in Oracle 10gR1. Currently we are in 11gR2. Every release dbms_scheduler gets more enhancements, where dbms_job has been static for many years.
Differences
dbms_scheduler has logging
dbms_scheduler has external jobs
dbms_scheduler has job chains
dbms_scheduler has job event handling (can raise and react upon events)
dbms_scheduler has resource manager integration
dbms_scheduler has human readable calendar syntax
dbms_scheduler can combine different calendars in a new one
In 11g extra
dbms_scheduler has remote external jobs
dbms_scheduler has light weight jobs - generate many low overhead jobs in one tx
dbms_scheduler can send mail on job completion
dbms_scheduler jobs can have multiple targets
dbms_job can only run pl/sql type of jobs in the current database.
I hope this (in complete list) helps

Both allow you to schedule jobs to be executed at a given time. The main difference is how you specify them, apart from that there is no noticeable difference in practice.
DBMS_SCHEDULER also allows you to set your custome schedule intervals, which DBMS_JOB doesn't. In fact,the most important difference is that DBMS_JOB is deprecated and will therefore be desupported before DBMS_SCHEDULER is.

Related

Run/execute multiple procedures in Parallel - Oracle PL/SQL

I have an Activity table which is getting all the table events of the system. Events like new orders, insertion/deletion on all the system tables will be inserted into this table. So, the no of events/sec is really huge for Activity table.
Now, I want to process the incoming events based on the business logic depending on the table responsible for raising the event. Every table may have different procedure to do the processing.
I used the same link
Parallelizing calls in PL/SQL
As a solution I have created multiple dbms_scheduler jobs which will be called at the same time. All these jobs (JOB1, JOB2--- - -JOB10) will have the same procedure (ProcForAll_Processing) as JOB_ACTION to achieve parallel processing.
begin
dbms_scheduler.run_job('JOB1',false);
dbms_scheduler.run_job('JOB2',false);
end;
ProcForAll_Processing: This procedure in turn will call 6 other procedures
Proc1,proc2,proc3 --- -- - -- - Proc6 in sequential manner. I want to achieve parallel processing for these as well.
P.S: We can’t create further jobs to achieve parallel processing in ProcForAll_Processing proc as it may lead to consume further resources and also DBA is not agreeing for creating further jobs. Also, I can't use
dbms_parallel_execute for parallel processing.
Please help me as I am really stuck to get it done
It is impossible in general case without jobs, and it will make multiple sessions for this. There is no such thing as multithreading PL\SQL with a few exceptions. One of them is parallel execution of sql statements [1]. So there are some attempts to abuse this stuff for parallel execution of PL\SQL code, for example try to look here [2].
But as i've said it's abuse IMHO.
Reference:
https://docs.oracle.com/cd/B19306_01/server.102/b14223/usingpe.htm
http://www.williamrobertson.net/documents/parallel-plsql-launcher.html
Get a new DBA. Or even better, cut them out of any decision making processes. A DBA should not review your code and should not tell you to not create jobs, unless there is a good, specific reason.
Using DBMS_SCHEDULER to run things in parallel is by far the easiest and most common way to achieve this result. Of course it's going to consume more resources, that's what parallelism will inevitably do.
Another, poorer option, is to use parallel pipelined table functions. It's an advanced PL/SQL feature that can't be easily explained in a simple example. The best I can do is refer you to the manual.
You should try to use DBMS_PARALLEL_EXECUTE (since RDBMS 11).
https://blogs.oracle.com/warehousebuilder/entry/parallel_processing_in_plsql
https://oracle-base.com/articles/11g/dbms_parallel_execute_11gR2

How to execute time consuming procedure asynchronously in Oracle

I need to execute a certain Oracle procedure from the client application and it usually takes longer time and can not really increase the waiting time for the response as the execution time is unpredictable!
Is there a way to execute the the procedure as a scheduler job asynchronously at run time?
If asynchronously executed would "Oracle AQ Asynchronous Notification" be used to notify back the application?
You can use the dbms_scheduler package (or the older dbms_job package) to run a procedure in a separate session asynchronously. Depending on the number of jobs you envision running (and the number of background jobs you want your application to write to some sort of job queue that a fixed number of background jobs read from to pick up and process work. That "job queue" could be an actual Oracle AQ queue or it could be a regular table that the jobs read from.
You could have the procedure send a message to the client using Oracle AQ as well. 99% of the time that I've seen this sort of setup, however, the job wrote some sort of status to a table (or just used the dbms_scheduler data dictionary) and the front-end merely polled the status periodically to determine when the job was done.

Is it possible to perform parallel nested transactions?

I've a scenario were I need to call a set of different Oracle procedures in parallel. These procedures must share the same initial context which has uncommitted transactions. I cannot commit the parent transaction under the danger of having read inconsistency between those parallel processes.
Is it possible in PL/SQL?
One thing comes to my mind: mapreduce with table functions http://blogs.oracle.com/datawarehousing/entry/mapreduce_oracle_tablefunction
I've used this in several scenarios to run things concurrently, though I'm not sure it is applicable to your problem.
You may be able to accomplish this using the DBMS_XA package, which allows you to "switch or share transactions across SQL*Plus sessions or processes using PL/SQL".
Oracle-Base has a good example of how to use the package.
(But if your goal is to use parallelism to improve performance you should use normal statement-level parallel execution instead.)
Far as I know: no.
DBMS_JOB and DBMS_SCHEDULER can be used to run Oracle procedures in parallel but they run them in their own sessions.

How should I implement a database cron job logger?

I use PHP and Oracle, with crontab executing the PHP scripts at scheduled times. My current logging/auditing solution involves simple log files. I'd like to save my cron execution logs to a database instead.
Right now I'm trying to design the process so that when a cron job starts I create a record in an CronExecution table. Then every time I want to log something for that cron I'll put a record in a CronEvent table which will have a foreign key to the CronExecution table.
I plan to log all events using a PRAGMA AUTONOMOUS pl/sql procedure. With this procedure I will be able to log events inside of other pl/sql procedures and also from my PHP code in a consistent manner.
To make it more robust, my plan is to have a fallback to log errors to a file in the event that the database log calls fail.
Has anybody else written something similar? What suggestions do you have based on your experience?
Yep, I've done this several times.
The CronExecution table is a good idea. However, I don't know that you really need to create the CronEvent table. Instead, just give yourself a "status" column and update that column.
You'll find that makes failing over to file much easier. As you build lots of these CronExecutions, you'll probably have less interest in CronEvents and more interest in the full status of the execution.
Wrap all of the update calls in stored procedures. You definitely have that correct.
Including a 'schedule' in your CronExecution will prove handy. It's very easy to have a lot of cron jobs and not be able to connect the dots on "how long did this take?" and "when is this supposed to run". Including a "next scheduled run" on completion of a job will make your life much easier.
You will want to read the documentation on DBMS_SCHEDULER.
It's a little bit of work to implement (what isn't?), but it will allow you to control scheduled and one-time jobs from within the database. That includes OS-level jobs.

Can We use threading in PL/SQL?

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.
+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.
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
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
For PL/SQL Parallel processing you have the following options:
DBMS_SCHEDULER (newer)
DBMS_JOB (older)
Parallel Query
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:
Advanced Queuing
DBMS_ALERT
DBMS_PIPE
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!
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.
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).
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
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.
Have you considered using Oracle Advaned Queuing?

Resources