无效的交易终止

Hen*_*nry 5 postgresql

我有一些程序,当我在 dbeaver 中执行时可以正常工作,没有问题,但是当我从外部程序调用它时,我收到以下错误。我不想在这里复制/粘贴完整的过程,因为它非常大并且可以在 db 工具中使用。我只是复制/粘贴顶部和底部。可能是什么原因造成的?

程序:

CREATE OR REPLACE PROCEDURE MyProcedure(lot of args..)
 LANGUAGE plpgsql
AS $procedure$
DECLARE
.....
.....
COMMIT;
END;
$procedure$
;
Run Code Online (Sandbox Code Playgroud)

错误:

ERROR: invalid transaction termination
  Where: PL/pgSQL function MyFunction line 185 at COMMIT  Call getNextException to see other errors in the batch. Line 185 at COMMIT  Call getNextException to see other errors in the batch.
Run Code Online (Sandbox Code Playgroud)

Lau*_*lbe 8

文档说:

事务控制只可能在CALLDO从顶层调用或嵌套CALLDO调用而没有任何其它中间命令。例如,如果调用堆栈是CALL proc1()? CALL proc2()? CALL proc3(),然后第二个和第三个过程可以执行事务控制动作。但是如果调用堆栈是CALL proc1()? SELECT func2()? CALL proc3(),那么最后一个过程不能做事务控制,因为SELECT中间。

还有一些其他未记录的限制:

  • 您不能显式地启动事务BEGIN并在事务内提交它。所以以下将失败:

    START TRANSACTION;
    CALL procedure_with_commit();
    
    Run Code Online (Sandbox Code Playgroud)

    这可能会在未来的版本中得到改进。

  • 调用堆栈中的所有过程必须用 PL/pgSQL 编写:

    CREATE PROCEDURE b() LANGUAGE plpgsql
       AS 'BEGIN PERFORM 42; COMMIT; END;';
    
    CREATE PROCEDURE a() LANGUAGE sql
       AS 'CALL b()';
    
    CALL a();
    ERROR:  invalid transaction termination
    CONTEXT:  PL/pgSQL function b() line 1 at COMMIT
    SQL function "a" statement 1
    
    Run Code Online (Sandbox Code Playgroud)

事实上,PostgreSQL 过程中的事务控制在某种程度上是有限的。

如果您违反了这些规则中的任何一条,您将收到您在问题中描述的错误消息。您可能必须在应用程序中而不是在过程中处理事务——也许将过程分成更小的部分使这成为可能。