2016-11-07 43 views
0

我有一段代碼塊需要一些時間才能完成,並且我在表上創建了一個進度變量,進程將更新,以便最終用戶可以知道剩下多少要完成。保存點和提交之間的衝突

問題在於代碼塊被視爲原子事務,因此進度變量值將只顯示0%或100%,除非我使用commit語句,該語句將刪除在上一個點上聲明的保存點塊,如果發生異常,它不會被識別爲有效。

的代碼是這樣的:

begin 
    /*do some stuff*/ 
    savepoint p_savepoint; 
    for q in (somequery) loop /*Really long loop*/ 
      /*Do some other stuff*/ 
      update t_sys_state set p1_progress = percentage 
      where user_id = 'theuserid'; 
      commit; /*This commit make the real progress value available*/ 
    end loop; 
    exception 
      when others then 
        rollback to p_savepoint; /*This savepoint is not recognized because of the previous commit*/ 
        raise; 
end; 

有沒有解決這個辦法嗎?

+4

如果你只是想顯示你的循環的進度,你可能要考慮使用'dbms_application_info'代替,它可以讓你把信息轉化爲'V $ session_longops',看例如這裏:http://stackoverflow.com/a/40154203/330315 –

+0

@a_horse_with_no_name謝謝,明天我會試試。 – Typo

回答

3

這聽起來像你想更新自動交易中的進度。這是使用自主交易很有意義的極少數情況之一。

CREATE OR REPLACE PROCEDURE log_progress(p_user IN varchar2, 
              p_percentage IN number) 
AS 
    PRAGMA autonomous_transaction; 
BEGIN 
    UPDATE t_sys_state 
    SET p1_progress = p_percentage 
    WHERE user_id  = p_user; 
    commit; 
END; 

然後

begin 
    /*do some stuff*/ 
    savepoint p_savepoint; 
    for q in (somequery) loop /*Really long loop*/ 
      /*Do some other stuff*/ 
      log_progress('theuserid', percentage); 
    end loop; 
    exception 
      when others then 
        rollback to p_savepoint; /*This savepoint is not recognized because of the previous commit*/ 
        raise; 
end; 
+0

不錯,我明天會試一試,謝謝。 – Typo