当Oracle计划作业被启用时,它是否在单独的会话中运行



我最近一直在学习使用Oracle的调度程序来异步运行作业。

我正在尝试构建只运行一次然后自动删除的作业。

我实现这一点的方法是将作业的MAX_RUNS属性设置为1,并将AUTO_DROP属性设置为TRUE。

我所有的作业默认是DISABLED的,因为我只手动启动它们。

我注意到作业没有被丢弃,这个问汤姆的线程解释了为什么。

因此,如果要自动删除作业,我必须在运行它们之前先启用它们。

然而,当一个作业被启用时,它被立即调度。

我的问题是:

当一个计划作业被启用,并因此被立即调度时,它是否在一个单独的会话中执行?

我需要所有的工作都被异步调度,因此我希望实现相同的行为:

DBMS_SCHEDULER.RUN_JOB(V_JOB_NAME, FALSE);

FALSE表示在单独的会话中异步调度作业。

我对启用一个作业并立即调度它的方法很满意,只要它在单独的会话中是异步的。

或者,如果有一种方法可以强制作业在启用时不被调度,那也会起作用。

我现在使用Oracle 11gR2

如果我有一堆需要运行的异步一次性作业,我会认真考虑使用旧的dbms_job包而不是dbms_scheduler来执行调度。然后你就像这样做

declare
  l_jobno pls_integer;
begin
  dbms_job.submit( l_jobno,
                   '<<what you want the job to do>>',
                   sysdate );
end;
/

这将导致一个新的会话打开,只要你提交submit运行你指定的任何代码。它将运行一次,然后从dba_jobs中移除。

或者,我会尝试重新构建系统,以便有一个后台"小部件处理器"作业,每隔几分钟运行一次,读取表以确定需要处理哪些小部件,并处理这些小部件。这可能比生成一个单独的作业来处理每个小部件更有意义。

当你想要更复杂的处理时,一个作业依赖于另一个作业,并且作业是基于事件启动的,

dbms_scheduler是很好的。但是,当您只需要一个非常轻量级的框架来完成非常简单的工作时,老派的dba_jobs真的很方便。

我发现,通过将新作业的START_DATE设置为将来的日期,并将REPEAT_INTERVAL设置为类似'FREQ= annual '的东西,那么作业将不会在启用时立即运行。

虽然不理想,但这将允许在通过DBMS_SCEHDULER手动运行时删除作业。RUN_JOB (V_JOB_NAME假);命令。

然而,这确实意味着作业被安排在未来的某个时间点运行。所以不要忘记手动运行它。在我的例子中,这很好,因为所有事情都发生在一个单独的调用中,但最好调用出来。

相关内容

最新更新