如何在PostgreSQL函数中使用提交和回滚

如何在PostgreSQL函数中使用提交和回滚,postgresql,postgresql-10,Postgresql,Postgresql 10,我使用三条insert语句,如果第三条语句中有错误,我想回滚第一条和第二条语句。如果没有办法做到这一点,请告诉我在PostgresqQL中处理此问题的不同方法 如果我使用提交或回滚,我会得到一个错误 CREATE OR REPLACE FUNCTION TEST1 () RETURNS VOID LANGUAGE 'plpgsql' AS $$ BEGIN INSERT INTO table1 VALUES (1); INSERT INTO table1

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

如果我使用
提交
回滚
,我会得到一个错误

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;$$;

上述代码不起作用COMMIT和
ROLLBACK

在函数中不能使用诸如
SAVEPOINT
COMMIT
ROLLBACK
之类的事务语句。说:

CALL
命令调用的过程以及匿名代码块(
DO
命令)中,可以使用命令
COMMIT
ROLLBACK
结束事务

例如否定,因为函数不是通过调用调用调用的过程,所以不能在函数中这样做

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


只需从函数中删除
COMMIT
,您就有了解决方案:由于整个函数始终在单个事务中运行,因此第三条语句中的任何错误都将导致
回滚
,这也会撤消前两条语句。

与其他SQL语言相比,您应该认为,当您在事务中时,Postgres总是隐式地负责在发生错误时的提交/回滚

以下是政府的说法:

事务是所有数据库系统的基本概念。事务的要点是,它将多个步骤捆绑到单个、全部或无操作中。这些步骤之间的中间状态对其他并发事务不可见,如果发生某些故障阻止事务完成,则所有步骤都不会影响数据库


这就是Postgres函数在默认情况下的行为方式(即,如果您的任何语句失败,将不会提交任何语句)。您可以使用dblinks来实现它,但我会重新考虑设计,更好地在测试之前发布它,感谢这些信息,我已经完成了测试。它工作得很好。但在我的例子中,我需要在插入数据后使用commit来执行pstgresql_fdw操作。那么,您能建议如何在插入后提交数据吗。@UmaShankar您可以使用dblink。@LaurenzAlbe,因此如果我需要更新一个表中的某些行,并通过if语句决定是删除另一个表中的相应行还是回滚(我的意思是取决于某些过程逻辑)那么就没有办法在函数内部将if与rollback结合起来?@GujaratSantana我在文档中添加了一段引语。
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;$$;