【问题标题】:Do PL/pgSQL functions autocommit on their own?PL/pgSQL 函数会自行自动提交吗?
【发布时间】:2021-07-17 00:36:05
【问题描述】:

我在 PostgreSQL 11 上有一个 PL/pgSQL 函数如下:

create or replace function public.process_single_usage(usage_p "UsagePs")
  returns text
  language plpgsql
as $function$
declare
return_msg text;
   -- Variables used for business logic
begin
   -- Business logic and error handling, return_msg variable is assigned to an error message on failure 
   -- or to an empty string on success.

   -- A bunch of insert statements if no error arises.
   return return_msg;
end
$function$;

我是否可以使用第二个函数在表的每一行上运行第一个函数,并在任何一行出现错误消息时回滚每个插入,或者我是否需要使用单个函数来控制事务?

【问题讨论】:

  • 该函数始终是调用者事务的一部分。而且你不能在函数中使用提交或回滚
  • 那么,既然一个函数正在调用,那是否意味着在给定时间有两个事务,一个嵌套另一个?
  • 不,一切都在由第一个函数的调用者定义的单个事务中运行
  • @a_horse_with_no_name:虽然这是真的,但我认为这不会妨碍 OP 试图实现的目标。我添加了一个答案。
  • 那么你有答案了吗?

标签: postgresql function transactions plpgsql commit


【解决方案1】:

我是否可以使用第二个函数在表的每一行上运行第一个函数,并在任何一行结果出现错误消息时回滚每个插入

FUNCTION 始终在单个事务中运行。但我不认为这会妨碍您尝试做的事情。带有EXCEPTION 子句的block 可以捕获异常并回滚子事务。根据“每个插入”的确切含义,这可能对您有用。

如果“每一行”是指整个操作中的每一行(子函数的多次调用),那么你不需要做任何额外的事情。如果发生异常,回滚一切是默认行为。

如果“每一行”是指受子函数的单个调用影响的每一行,那么考虑the manual on Trapping Errors:

EXCEPTION 子句捕获到错误时,局部变量 PL/pgSQL 函数的 PL/pgSQL 函数保持错误发生时的状态, 但是块内对持久数据库状态的所有更改都是 回滚

我的大胆强调。相关:

要真正 COMMIT 在过程中的任何点工作,您需要一个 PROCEDURE,它在 Postgres 11 中引入。从相同版本开始,事务控制语句也允许在使用 DO command 执行的匿名代码块中.

基本上:

DO
$do$
DECLARE
  _rec "UsagePs";
BEGIN
   FOR _rec IN
      SELECT * FROM "UsagePs" u WHERE u.foo = 'bar' ORDER BY u.id
   LOOP
      BEGIN 
         PERFORM public.process_single_usage(_rec);
         -- COMMIT; -- ? -- requires Postgres 11
      EXCEPTION
         WHEN OTHERS THEN
            RAISE WARNING 'This error happened: %!', SQLERRM;
      END;
   END LOOP;
END
$do$;

我认为您甚至不需要或不想在循环中使用COMMIT。您只想回滚子事务 - 或所有内容。

注意使用SQLERRM 将任何错误消息从子函数传播出去,降级为WARNINGThe manual:

特殊变量SQLERRM 包含与异常相关的错误消息。

相关:

【讨论】:

    猜你喜欢
    • 2013-08-05
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2012-03-27
    • 2018-02-10
    相关资源
    最近更新 更多