2015-11-02 100 views
1

我有7個需要按計劃刷新的物化視圖。Oracle dbms_job.submit:混合同步和異步

其中五個數據源是獨立的,可以異步重建。我想我用像湯姆描述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; 

其中兩個是依賴於一些前五MViews和需要等到那些已刷新。後兩者彼此獨立,可以同時運行。

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」過程?

+4

請看看使用dbms_scheduler。 dbms_job不應該用於新開發,並且最好是「古怪」(例如,如果作業失敗,它將嘗試重新啓動自身以及其他陷阱)。在dbms_scheduler中,你想要的是一個作業鏈 – tbone

+1

,並且問tom的鏈接是從2002年開始用於Oracle 8的。有更好的方式來做事情,因爲@tbone表示工作鏈接 – kevinsky

+0

感謝@tbone和kevinsky的洞察力!我沒有意識到我正在實施Oracle 8級解決方案。在閱讀您的評論並看到Justin Cave的回答後,我開始研究如何使用鏈條。這是比我先做的更好的方法。如果有人感興趣,我會在單獨的帖子中分享我的最終解決方案。 – Deejers

回答

1

最簡單的方法將是從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過程返回需要被監控,以便refresh_all_mviews過程調用refresh_independent_mviews,實現了循環,然後調用refresh_dependent_mviews就業數據的收集。

您可以通過將作業寫入記錄成功或失敗的表,或通過Oracle AQ發送另一個進程偵聽的消息以啓動依賴mview刷新來獲得更復雜的結果。在這種情況下可能不需要這樣做,但如果您的依賴關係變得更加複雜,那可能會是這樣毫無疑問,你也可以創建一個可以爲你做到這一點的鏈。

+0

謝謝你的答案賈斯汀!您的解決方案可以解答我的問題。我將改變我的方法來使用DBMS_SCHEDULER鏈。我會在另一篇文章中分享我的解決方案,以防其他人感興趣。 – Deejers