Oracle dbms_job.submit:混合同步和异步

时间:2015-11-02 17:54:05

标签: oracle asynchronous oracle11g synchronous

我有7个物化视图需要按计划刷新。

其中五个是独立于数据源的,可以异步重建。我想用汤姆描述here

之类的东西
PROCEDURE refresh_Independent_MViews AS
l_job       BINARY_INTEGER;
BEGIN
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''IndependentMView1'', method => ''C'') ;') ;
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''IndependentMView2'', method => ''C'') ;') ;
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''IndependentMView3'', method => ''C'') ;') ;
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''IndependentMView4'', method => ''C'') ;') ;
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''IndependentMView5'', method => ''C'') ;') ;
END refresh_Independent_MViews;

其中两个依赖于前五个MView中的一些,需要等到刷新后再进行刷新。最后两个是相互独立的,可以同时运行。

PROCEDURE refresh_Dependent_MViews AS
l_job       BINARY_INTEGER;
BEGIN
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''DependentMView1'', method => ''C'') ;') ;
  dbms_job.submit (l_job, 'DBMS_MVIEW.REFRESH(list => ''DependentMView2'', method => ''C'') ;') ;
END refresh_Dependent_MViews;

问题:在启动异步作业后,调用“refresh_Independent_MViews”会很快返回工作,但我无法判断各个异步作业何时完成了他们的工作。

问题:有没有办法知道dbms_job.submit完成的异步作业何时全部完成,所以我知道何时启动“refresh_Dependent_MViews”程序?

2 个答案:

答案 0 :(得分:1)

最简单的方法是从l_job获取dbms_job.submit输出参数,然后编写一个循环来检查job中有多少dba_jobs个值,当计数为0时退出,否则通过呼叫dbms_lock.sleep睡眠一段合理的时间。显然,您需要避免覆盖当前的l_job变量以捕获所有五个作业。像

这样的东西
CREATE TYPE num_tbl
    AS TABLE OF NUMBER;

PROCEDURE refresh_all_MViews AS
  l_job       BINARY_INTEGER;
  l_jobs      num_tbl;
BEGIN
  l_jobs.extend(5);
  dbms_job.submit (l_job, ...) ;
  l_jobs(1) := l_job;
  dbms_job.submit (l_job, ...) ;
  l_jobs(2) := l_job;
  dbms_job.submit (l_job, ...) ;
  l_jobs(3) := l_job;
  dbms_job.submit (l_job, ...) ;
  l_jobs(4) := l_job;
  dbms_job.submit (l_job, ...) ;
  l_jobs(5) := l_job;

  loop
    select count(*)
      into l_cnt
      from dba_jobs
     where job in (select column_value from table(l_jobs));

    if( l_cnt = 0 )
    then
      exit;
    end if;

    dbms_lock.sleep( 10 ); -- Sleep for 10 seconds
  end loop;

  refresh_Dependent_MViews;

END refresh_all_MViews;

现在,您显然可以修改refresh_Independent_MViews过程以返回需要监视的作业号集合,以便refresh_all_mviews过程调用refresh_independent_mviews,实现循环,然后致电refresh_dependent_mviews

通过让您的作业写入记录成功或失败的表,或通过Oracle AQ发送另一个进程监听的消息以启动依赖的mview刷新,您可以变得更加复杂。在这种情况下可能不需要,但可能是你的依赖变得更复杂。毫无疑问,您还可以创建一个dbms_scheduler链,为您执行此操作。

答案 1 :(得分:0)

使用DBMS_SCHEDULER链,步骤和命名程序是同步和异步刷新MView的更好方法。首先,它提供了精确的时序控制。

What is a better way to do synchronous and asynchronous MView refreshes in Oracle 11g?