存储过程是否在Postgres中的数据库事务中运行?

时间:2015-01-31 10:02:04

标签: database postgresql stored-procedures transactions relational-database

如果存储过程在中间失败,那么从SP开头那时的更改是否会隐式回滚,还是我们必须编写任何显式代码以确保SP仅在数据库事务中运行?

2 个答案:

答案 0 :(得分:25)

严格地说,Postgres目前(不包括版本10)具有“存储过程”,如ANSI标准中所定义。一切都是用“函数”完成的,它们提供了与其他RDBMS提供的存储过程相同的功能(和更多)。主要区别在于交易处理。

True stored procedures最终在Postgres 11中引入:

Postgres中

Functions atomic 并自动在自己的事务中运行,除非在外部事务中调用。它们总是在单个事务中运行,并且完全成功或失败。因此,无法在函数内开始或提交事务。并且不允许在事务块中运行的VACUUMCREATE INDEX CONCURRENTLY等命令。

Per documentation on PL/pgSQL:

  

函数和触发程序总是在a中执行   由外部查询建立的事务 - 它们无法启动或   提交该事务,因为它们没有上下文   执行。但是,包含EXCEPTION子句的块   有效地形成一个可以无需回滚的子事务   影响外部交易。

Error handling:

  

默认情况下,PL / pgSQL函数中发生的任何错误都会中止   执行该功能,实际上是周围的交易   同样。您可以使用BEGIN来捕获错误并从中恢复   使用EXCEPTION子句阻止。

有特殊的例外,包括但不限于:

  • 写入日志文件的数据
  • changes made to a sequence

      

    重要:某些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