How to execute time consuming procedure asynchronously in Oracle - 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.

Related

Oracle scheduler JOBS: get argument_value used in a specific job instance

I have a Oracle Scheduler Job configured in my DB 19c. This is as event-based job, with a queue table created used in this process.
I need to analyse a possible problem in one of this executions. In DBA_SCHEDULER_JOB_LOG table I have the instance and a JOB_SUBNAME called SCHED$_EVTPARINST_89121.
Although I don't have DBA privileges, I have two questions:
How can I get the parameters values passed to this scheduler Job instance?
How can I get the Log (history) of enqueue messages, with enqueue date and set_job_argument_value associated to each enqueue message?
I've tried to check in Oracle documentation (https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/scheduling-jobs-with-oracle-scheduler.html#GUID-E9B234FF-C7F3-44B0-AEC8-A997353C414F or https://docs.oracle.com/database/121/ARPLS/d_aq.htm#ARPLS004) without success.
Thanks.

Oracle DBMS_SCHEDULER job to monitor a DBMS_ALERT

Env: Oracle 12c R2
Trying to understand what the best approach would be to set up an Oracle DBMS_SCHEDULER job that would be used to monitor a DBMS_ALERT trigger that checks when a specific column value changes within a table.
The thing is, this table column value change will sometimes occur on a frequent basis and sometimes it may only occur twice a day but I will need to monitor this column change via the DBMS_ALERT.
The trigger I have is as follows and I have a procedure called check_signal that checks for the signal that I wish to use within the DBMS_SCHEDULER job.
The goal that I am trying to achieve is that I am going to have the situation where I will need to run say, three jobs:
Job1
Job2
Job3
The thing is, the payload returned from Job1 is required and and passed as parameters into Job2 and again, the payload returned from Job2 is required and passed as parameters into Job3.
It is this wait/alert that I am trying to achieve through the use of DBMS_ALERTS.
create or replace trigger my_tab_upd after update of status on my_tab for each row
begin
dbms_alert.signal('mystatusalert', 'changed from '||:old.status||' to '||:new.status||'.');
end;
/
This will be used via a web-based application which is used by multiple users.
Just unsure on how to setup this scheduled job that will continuously check for the alert and then be used within the web app.
If there is a better means than DBMS_ALERT, then please let me know.
The general answer is simple, while polling for events every N seconds you get an average delay N/2 seconds and maximal delay of N seconds.
In context of DBMS_ALERT you should re-think this approach, as this will implement polling with wait on the event.
The periodically executed jobs make basically tho thinks:
DBMS_ALERT.REGISTER on an event name
wait with DBMS_ALERT.WAITONE
Assume that the DBMS_SCHEDULER jobs runs every 10 seconds and it is started in the phase with frequent signalling. So the first execution returns quickly after receiving an event.
The second execution falls in the quite period, so the job will wait hours to get an event.
I think this is not what you expect as
1) the waiting job will have an open session - what you want to avoid as follows from you other question
You may use timeout = 0 in the DBMS_ALERT.WAITONE, but this will return close to no events, except those fired accidentally between the REGISTER and WAITONE
2) if in the first 10 seconds two events are signalled, the second one will be lost as at the signaling time the subscribing job is not active and no registration exists.

best practices with Oracle DBMS_Scheduler

what's good for Oracle DBMS_Scheduler?
keeping a job scheduled(disabled) every time. and enable it and run it when needed.
create the job ,run it and drop it.
I have a table x and whenever a records gets submitted to that table ,I should have a job to process that record.
we may or may not have the record insertions always..
Keeping this in mind..what's better...?
Processing rows as they appear in a table in an asynchronous process can be done in a number of different ways, choose the way that suits you:
Add a trigger to the table which creates a one-off job to process the row using DBMS_JOB. This is suitable if the volume of data being inserted to the table is quite low, and you don't want your job running all the time. The advantage of DBMS_JOB is that the job will not start until the insert is committed; if it is rolled back, the job is also rolled back so doesn't run. The disadvantage is that if there is a sustained spike of activity, all the jobs created will crowd out any other jobs that are running.
Create a single job using DBMS_SCHEDULER which runs regularly, polls the table for new records and processes them. This method would need a column on the table that it can update to mark each record as "processed". For example, add a VARCHAR2(1) flag which is set to 'Y' on insert and set to NULL by the job after processing. You could add an index to that flag which will only store entries for unprocessed rows (so it will be small and fast). This method is much more efficient, especially for large data volumes, because each run of the job can effectively process large chunks of data in bulk at a time.
Use Oracle Advanced Queueing. http://docs.oracle.com/cd/E11882_01/server.112/e11013/aq_intro.htm#ADQUE0100
For (1), a separate job is created for each record in the table. You don't need to create the jobs. You do need to monitor them, however; if one fails, you would need to investigate and re-run manually.
For (2), you just create one job and let it run regularly. If one record fails, it could be picked up by the next iteration of the job. I would process each record in a separate transaction so the failure of one record doesn't affect the failure of other records still in the queue.
For (3), you still create a job like (2) but instead of reading the table it pulls requests off a queue.

Reduce execution time of Oracle stored procedure

I have a db job running daily that manages to process 10.000 rows from a table of 3.500.000 rows, in three hours.
Tuning the main cursor's select statement can only save me 30 minutes, but I need to reduce the job running time from 3 hours to 10-15 minutes.
I have to state that there is only the main loop for the cursor and for each record there are calls to external systems, in order to get or send data, so this is an overhead I cannot control. The time for each record to be processed after it is fetched is a little less than a second and that is not acceptable ...
Is there something I could do? All ideas are more than welcome!
Imho, you can submit job for each query to external system or try to run in parallel, may be you can use ADVANSED QUEUE. Explain: send each selected row to queue, and quering to external will proceed with AQ
You may try to process rows in parallel.

job VS Scheduler, Oracle 10G

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.

Resources