如何在 PostgreSQL 函数中使用 COMMIT 和 ROLLBACK

how to use COMMIT and ROLLBACK in a PostgreSQL function

我正在使用三个插入语句,如果第三个语句有错误,我想回滚第一个和第二个。如果没有办法做到这一点,请告诉我在 PostgresqQL 中处理这个问题的不同方法。

如果我使用 COMMITROLLBACK,我会得到一个错误。

CREATE OR REPLACE FUNCTION TEST1 ()
   RETURNS VOID
   LANGUAGE 'plpgsql'
   AS $$
BEGIN 

    INSERT INTO table1 VALUES (1);

    INSERT INTO table1 VALUES (2);

    INSERT INTO table1 VALUES ('A');
    COMMIT;
EXCEPTION
   WHEN OTHERS THEN
   ROLLBACK;
END;$$;

以上代码无效; PostgreSQL 函数不支持 COMMITROLLBACK

您不能在函数中使用像 SAVEPOINTCOMMITROLLBACK 这样的事务语句。 The documentation 说:

In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK.

Ex negativo,因为函数不是用 CALL 调用的过程,你不能在函数中这样做。

PL/pgSQL中启动块的BEGIN与启动事务的SQL语句BEGIN不同。

只要从你的函数中删除 COMMIT,你就有了解决方案:因为整个函数总是 运行 在一个事务中,第三个语句中的任何错误都会导致 ROLLBACK 这也撤消了前两个语句。

与其他 SQL 语言相比,您应该认为 Postgres 总是会在发生错误时隐式地处理 commit/rollback 当您在事务中时.

doc 是这样说的:

Transactions are a fundamental concept of all database systems. The essential point of a transaction is that it bundles multiple steps into a single, all-or-nothing operation. The intermediate states between the steps are not visible to other concurrent transactions, and if some failure occurs that prevents the transaction from completing, then none of the steps affect the database at all.

CREATE OR REPLACE FUNCTION TEST1 ()
   RETURNS VOID
   LANGUAGE 'plpgsql'
   AS $$
BEGIN 

    INSERT INTO table1 VALUES (1);

    INSERT INTO table1 VALUES (2);

    INSERT INTO table1 VALUES ('A');
    COMMIT;
EXCEPTION
   WHEN OTHERS THEN
   ROLLBACK;
END;$$;