【问题标题】:Commit the transaction after exception is raised引发异常后提交事务
【发布时间】:2018-02-24 02:14:06
【问题描述】:

我尝试寻找解决方案,但没有找到。我知道一旦引发异常,postgres 就会回滚所有事务。但我的要求是将某个异常记录到数据库表中。

以下是示例代码:

CREATE OR REPLACE FUNCTION fn_test(
in_var numeric DEFAULT NULL::numeric)
RETURNS numeric AS
$BODY$
DECLARE
BEGIN
IF in_var=0
THEN
    RAISE EXCEPTION using errcode='INELG';
ELSE IF in_var=1
THEN
    RAISE EXCEPTION using errcode='INVAL';
ELSE
    RETURN in_var;
END IF;
begin
EXCEPTION
WHEN sqlstate 'INELG' 
THEN
    INSERT INTO LOG_TBL(in_par,error_reason)
    VALUES(in_var,'VALUE INELGIBLE');
    RAISE EXCEPTION 'Unable to Process: Parameter Not Eligible';
WHEN sqlstate 'INVAL' 
THEN
    INSERT INTO LOG_TBL(in_par,error_reason)
    VALUES(in_var,'VALUE INValid');
    RAISE EXCEPTION 'Unable to Process: Parameter Invalid';
end; 

END;    
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100;

我面临的问题是,一旦引发异常,异常部分的 LOG_TBL 中的记录就会回滚。是否有替代解决方案可以将记录插入数据库表并引发应用程序错误?

【问题讨论】:

  • 为什么不在插入之后和引发最后一个异常之前发出 COMMIT?
  • @RicardoC - ASOAN 不能 - 自定义函数在事务内部而不是外部运行。
  • @RichardHuxton 对...我刚刚了解到 Postgres 没有嵌套事务。嗯,保存点,也许?我想我们需要从 ASOAN 确定他是否想回滚在调用函数之前采取的操作,因为函数内部的 COMMIT 可能仍然是答案......我认为。
  • @RicardoC - 是的,保存点是一个嵌套事务,这就是上面用来捕获异常的内容。不过,这不是他需要的——这是一个独立/分离的事务,因此即使“主”事务回滚,也可以提交对日志表的写入。

标签: postgresql plpgsql


【解决方案1】:

以一种简单的方式 - 你不能。一旦你进入一个函数,就是这样。

您要么必须在客户端层执行此操作,要么在另一个连接上循环返回以记录错误。传统上,您会通过dblink 循环返回,但也可以使用Foreign Data Wrappers - 我不得不承认我不确定。

编辑:不,它看起来像 postgres_fdw syncs the transactions 在本地和远程之间。在这种情况下没有帮助。看起来 dblink 是显而易见的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多