来自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;
答案 0 :(得分:14)
功能确实代表交易。您不必在BEGIN / COMMIT中包装函数。
答案 1 :(得分:4)
您不能在函数中使用commit或rollback命令,但可以将函数用于已提交的事务,
开始交易; SELECT do_something(); COMMIT;
如果do_something中没有异常,则此SQL脚本仅提交,然后,它将回滚函数的事务。
答案 2 :(得分:1)
docs这样说:
保存点是事务内部的一个特殊标记,它允许回滚建立后执行的所有命令,并将事务状态恢复为保存点时的状态。
他们也给出了例子。
修改强>
您需要在BEGIN和COMMIT命令中包装transaction。
通过使用BEGIN和COMMIT命令
包围事务的SQL命令来设置事务
答案 3 :(得分:1)
保存点可用于模拟嵌套事务。由于postgresql事务是一系列将被应用或丢弃的语句,因此保存点可以标记该序列中允许回滚的点。
由于不支持真正的嵌套交易,这是您最好的选择(也是一个很好的选择)。