Oracle dbms_job.submit:混合同步和异步
Oracle dbms_job.submit: Mixing Synchronous and Asynchronous
我有 7 个物化视图需要按计划刷新。
其中五个与数据源无关,可以异步重建。我想使用 Tom 描述的东西 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" returns,但我无法判断各个异步作业何时全部完成工作。
问题:有没有办法知道 dbms_job.submit 启动的异步作业何时全部完成,以便我知道何时开始 "refresh_Dependent_MViews" 程序?
最简单的方法是从 dbms_job.submit
获取 l_job
输出参数,然后编写一个循环来检查 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
过程修改为 return 需要监视的作业编号集合,以便 refresh_all_mviews
过程调用 refresh_independent_mviews
,执行循环,然后调用 refresh_dependent_mviews
。
您可以通过将作业写入记录成功或失败的 table 或通过 Oracle AQ 发送消息让另一个进程侦听以启动相关的 mview 刷新来变得更加复杂。在这种情况下可能不需要,但如果您的依赖关系变得更加复杂,则可能需要。毫无疑问,您还可以创建一个 dbms_scheduler
链来为您执行此操作。
使用 DBMS_SCHEDULER 链、步骤和命名程序是同步和异步刷新 MView 的更好方法。一方面,它提供了精确的时序控制。
我有 7 个物化视图需要按计划刷新。
其中五个与数据源无关,可以异步重建。我想使用 Tom 描述的东西 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" returns,但我无法判断各个异步作业何时全部完成工作。
问题:有没有办法知道 dbms_job.submit 启动的异步作业何时全部完成,以便我知道何时开始 "refresh_Dependent_MViews" 程序?
最简单的方法是从 dbms_job.submit
获取 l_job
输出参数,然后编写一个循环来检查 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
过程修改为 return 需要监视的作业编号集合,以便 refresh_all_mviews
过程调用 refresh_independent_mviews
,执行循环,然后调用 refresh_dependent_mviews
。
您可以通过将作业写入记录成功或失败的 table 或通过 Oracle AQ 发送消息让另一个进程侦听以启动相关的 mview 刷新来变得更加复杂。在这种情况下可能不需要,但如果您的依赖关系变得更加复杂,则可能需要。毫无疑问,您还可以创建一个 dbms_scheduler
链来为您执行此操作。
使用 DBMS_SCHEDULER 链、步骤和命名程序是同步和异步刷新 MView 的更好方法。一方面,它提供了精确的时序控制。