我具有以下功能,该功能由Web API调用以导入一些上传的数据。还有一个upload_log
表,该表保存上传状态,并且可以通过API进行轮询。
我的问题特定于Postgresql事务管理:我知道BEGIN...END
块之间的所有事务都是PG中的事务,并且一旦一个语句失败,它将自动回滚。
因此,永远不要将异常写入到upload_log表中?
尽管如此,我在我的upload_log中收到错误消息,但我问自己为什么会这样。
PERFORM...
吗? EXCEPTION WHEN OTHERS...
之后可以在表中写入内容吗? ROLLBACK
?
CREATE OR REPLACE FUNCTION finalize_upload(sync_id in varchar)
RETURNS void AS $$
DECLARE
vCount numeric;
err1 text;
err2 text;
err3 text;
BEGIN
-- Mark as Upload in Progress
update upload_log
set
sync_status='1'
where
upload_log.gto_sync_id=finalize_upload.sync_id;
begin
vCount := 1;
-- do some heavy stuff
-- move data from import tables into production
perform finalize_upload_specific(finalize_upload.sync_id);
exception when others then
GET STACKED DIAGNOSTICS err1 = MESSAGE_TEXT,
err2 = PG_EXCEPTION_DETAIL,
err3 = PG_EXCEPTION_HINT;
-- Mark Upload as failed
update upload_log
set
END_DATE=current_timestamp,
sync_status='-1',
err_hint=err1||' '||err2||' '||err3
where
upload_log.sync_id=finalize_upload.sync_id;
end
;
END
$$ LANGUAGE plpgsql;
答案 0 :(得分:1)
PL / pgSQL块中BEGIN
和关联的EXCEPTION
之间的所有操作都将在子事务中执行。
如果抛出任何已处理的异常,则子事务将回滚,但封闭的事务将继续。异常处理程序中的UPDATE
将被提交,因为它已经在要回滚的子事务之外。
使用伪代码和SQL保存点进行说明:
START TRANSACTION;
UPDATE upload_log SET sync_status='1' ...;
SAVEPOINT a;
SELECT finalize_upload_specific($1);
-- if an exception was thrown:
ROLLBACK TO SAVEPOINT a;
RELEASE SAVEPOINT a;
UPDATE upload_log SET sync_status='-1' ...;
COMMIT;
-- else
ROLLBACK;