如何在PostgreSQL函数中使用提交和回滚
我使用三条insert语句,如果第三条语句中有错误,我想回滚第一条和第二条语句。如果没有办法做到这一点,请告诉我在PostgresqQL中处理此问题的不同方法 如果我使用如何在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
提交
或回滚
,我会得到一个错误
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;$$;
上述代码不起作用
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;$$;