为什么不能在PostgreSQL过程中使用Commit和rollback?

时间:2017-02-20 17:22:16

标签: postgresql stored-procedures

我正在PostgreSQL数据库上创建程序。我读过这些程序中不可能使用回滚。

为什么?

是否可以使用commit?

我想这与ACID属性有关,但是如果我们在一个过程中有两个插入操作会怎样。如果第二个失败,第二个得到回滚?

谢谢。

2 个答案:

答案 0 :(得分:3)

Postgres' overview通过解释其功能与传统存储过程的不同之处给出了一个提示:

  

使用PL / pgSQL创建的函数可以在任何可以使用内置函数的地方使用。例如,可以创建复杂的条件计算函数,然后使用它们来定义运算符或在索引表达式中使用它们。

这使得在每个可能的情况下支持函数内的事务变得尴尬。来自the docs

  

函数和触发器过程总是在外部查询建立的事务中执行...但是,包含EXCEPTION子句的块有效地形成了一个可以回滚而不影响外部事务的子事务。

如果你在一个函数中有两个INSERT,第一个可以包装在EXCEPTION块中以捕获任何错误并决定是否应该执行第二个错误。

答案 1 :(得分:1)

你是对的。您无法在过程中回滚在过程之前启动的事务。此外,也无法在过程中创建事务。您会收到此错误:

ERROR: cannot begin/end transactions in PL/pgSQL
SQL state: 0A000
Hint: Use a BEGIN block with an EXCEPTION clause instead.

正如此错误所述,并且正如Matt所提到的,您可以使用异常块来实质上执行回滚。来自help

  

当EXCEPTION子句捕获到错误时,PL / pgSQL函数的局部变量保持与发生错误时相同,但会回滚块中持久数据库状态的所有更改。

或者,您可以在事务中调用该过程,并在必要时将其回滚。