如果存储过程在中间失败,那么从SP开头那时的更改是否会隐式回滚,还是我们必须编写任何显式代码以确保SP仅在数据库事务中运行?
答案 0 :(得分:25)
严格地说,Postgres目前(不包括版本10)具有“存储过程”,如ANSI标准中所定义。一切都是用“函数”完成的,它们提供了与其他RDBMS提供的存储过程相同的功能(和更多)。主要区别在于交易处理。
True stored procedures最终在Postgres 11中引入:
Postgres中 Functions是 atomic 并自动在自己的事务中运行,除非在外部事务中调用。它们总是在单个事务中运行,并且完全成功或失败。因此,无法在函数内开始或提交事务。并且不允许在事务块中运行的VACUUM
或CREATE INDEX CONCURRENTLY
等命令。
Per documentation on PL/pgSQL:
函数和触发程序总是在a中执行 由外部查询建立的事务 - 它们无法启动或 提交该事务,因为它们没有上下文 执行。但是,包含
EXCEPTION
子句的块 有效地形成一个可以无需回滚的子事务 影响外部交易。
默认情况下,PL / pgSQL函数中发生的任何错误都会中止 执行该功能,实际上是周围的交易 同样。您可以使用
BEGIN
来捕获错误并从中恢复 使用EXCEPTION
子句阻止。
有特殊的例外,包括但不限于:
重要:某些PostgreSQL数据类型和函数有特殊规则 关于交易行为。特别是对a做出的改变 序列(因此使用
serial
声明的列的计数器) 对所有其他事务立即可见,并且不会滚动 如果进行更改的事务中止,则返回。
准备好的陈述
dblink调用(或类似)
答案 1 :(得分:0)
来自Postgresql官方文档:
<块引用>在 CALL 命令调用的过程以及匿名代码中 块(DO 命令),可以使用 命令 COMMIT 和 ROLLBACK。一个新的事务开始 使用这些命令结束交易后自动,所以 没有单独的 START TRANSACTION 命令。 (注意 BEGIN 和 END 在 PL/pgSQL 中有不同的含义。)
https://www.postgresql.org/docs/11/plpgsql-transactions.html