11

来自 MS SQL 世界,我倾向于大量使用存储过程。我目前正在编写一个使用大量 PostgreSQL plpgsql 函数的应用程序。如果我在其中的任何时候遇到异常,我想做的是回滚包含在特定函数中的所有 INSERTS/UPDATES。

我最初的印象是每个函数都包装在它自己的事务中,并且异常会自动回滚所有内容。然而,情况似乎并非如此。我想知道我是否应该将保存点与异常处理结合使用?但我并不真正了解事务和保存点之间的区别,以了解这是否是最好的方法。请问有什么建议吗?

CREATE OR REPLACE FUNCTION do_something(
         _an_input_var int
                ) RETURNS bool AS $$
        DECLARE
                _a_variable int;
        BEGIN
                INSERT INTO tableA (col1, col2, col3)
                        VALUES (0, 1, 2);

                INSERT INTO tableB (col1, col2, col3)
                        VALUES (0, 1, 'whoops! not an integer');

                -- The exception will cause the function to bomb, but the values 
                -- inserted into "tableA" are not rolled back.    

                RETURN True;
END; $$ LANGUAGE plpgsql;
4

4 回答 4

17

一个函数确实代表一个事务。您不必在 BEGIN/COMMIT 中包装函数。

于 2010-03-11T17:45:15.710 回答
4

您不能在函数中使用提交或回滚命令,但可以将函数用于已提交的事务,

开始交易;选择 do_something(); 犯罪;

这个 SQL 脚本只有在 do_something 中没有异常的情况下才会提交,然后,它会回滚函数的事务。

于 2012-03-14T01:54:03.923 回答
1

文档是这样说的:

保存点是事务中的一个特殊标记,它允许在建立后执行的所有命令回滚,将事务状态恢复到保存点时的状态。

他们也举了例子。

编辑:

您需要在 BEGIN 和 COMMIT 命令中包装事务。

通过使用 BEGIN 和 COMMIT 命令围绕事务的 SQL 命令来设置事务

于 2010-03-11T03:01:42.410 回答
1

保存点可用于模拟嵌套事务。因为 postgresql 事务是一系列将被应用或丢弃的语句,所以保存点可以标记该序列中允许回滚的点。

由于不支持真正的嵌套事务,因此这是您最好的选择(也是一个很好的选择)。

于 2010-03-11T03:03:35.893 回答