我有一个代码块需要一些时间才能完成,并且我已经在一个表上创建了一个进程变量,该进程将更新,以便最终用户可以知道还有多少剩余要完成。
问题是代码块被视为原子事务,所以进度变量值只显示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;
有什么方法吗?
答案 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;