【问题标题】:Invalid transaction termination交易终止无效
【发布时间】:2019-12-03 14:15:42
【问题描述】:

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

程序:

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

错误:

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.

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    The documentation 说:

    事务控制只能在来自顶层的CALLDO 调用或嵌套CALLDO 调用中进行,而无需任何其他干预命令。比如调用栈是CALL proc1()CALL proc2()CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()SELECT func2()CALL proc3(),那么最后一个过程就不能做事务控制,因为中间有SELECT

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

    • 您不能使用BEGIN 显式启动事务并将其提交到事务中。所以下面会失败:

      START TRANSACTION;
      CALL procedure_with_commit();
      

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

    • 调用堆栈中的所有过程都必须用 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
      

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 2014-09-28
      • 2013-08-24
      • 2014-06-22
      • 2015-11-26
      • 2013-08-09
      相关资源
      最近更新 更多