我正在PostgreSQL数据库上创建程序。我读过这些程序中不可能使用回滚。
为什么?
是否可以使用commit?
我想这与ACID属性有关,但是如果我们在一个过程中有两个插入操作会怎样。如果第二个失败,第二个得到回滚?
谢谢。
答案 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函数的局部变量保持与发生错误时相同,但会回滚块中持久数据库状态的所有更改。
或者,您可以在事务中调用该过程,并在必要时将其回滚。