保存点和提交之间的冲突

时间:2016-11-07 22:16:57

标签: plsql oracle11g

我有一个代码块需要一些时间才能完成,并且我已经在一个表上创建了一个进程变量,该进程将更新,以便最终用户可以知道还有多少剩余要完成。

问题是代码块被视为原子事务,所以进度变量值只显示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;

有什么方法吗?

1 个答案:

答案 0 :(得分: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;