postgresql 无效的事务终止

vd2z7a6w  于 2023-03-29  发布在  PostgreSQL
关注(0)|答案(2)|浏览(388)

我有一些程序,当我在dbeaver中执行时,它工作正常,没有问题,但是当我从外部程序调用它时,我在下面得到错误。我不想复制/粘贴完整的程序,因为它很大,它在数据库工具中工作。我只是复制/粘贴顶部和底部。这可能是什么原因?

程序:

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.
afdcj2ne

afdcj2ne1#

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过程中的事务控制是有限的。
如果你违反了这些规则中的任何一条,你将得到你在问题中描述的错误消息。你可能不得不在应用程序中而不是在过程中处理事务-也许将过程分成更小的部分可以做到这一点。

fnx2tebb

fnx2tebb2#

在我的例子(v12)中,问题是过程声明中的SET time zone UTC
一旦我删除它,错误就消失了。
它实际上被记录了下来:
如果SET子句附加到过程,则该过程不能执行事务控制语句(例如,COMMIT和ROLLBACK,具体取决于语言)。

相关问题