【发布时间】:2015-03-30 18:48:45
【问题描述】:
如果存储过程在中间失败,那么从 SP 开始时的更改是否会隐式回滚,或者我们是否必须编写任何显式代码以确保 SP 仅在数据库事务中运行?
【问题讨论】:
-
手册中涵盖了所有内容。包括从技术上讲,您在 PostgreSQL 中没有存储过程
标签: database postgresql stored-procedures transactions relational-database
如果存储过程在中间失败,那么从 SP 开始时的更改是否会隐式回滚,或者我们是否必须编写任何显式代码以确保 SP 仅在数据库事务中运行?
【问题讨论】:
标签: database postgresql stored-procedures transactions relational-database
严格来说,Postgres 没有stored procedures 在版本 11 之前的 ISO/IEC 标准中定义。该术语经常被错误地用于指代 functions,它提供了许多与其他 RDBMS 提供的“存储过程”相同的功能(甚至更多)。主要区别在于事务处理。
True stored procedures 终于在 Postgres 11 中引入:
Functions 在 Postgres 中是 atomic 并自动在它们自己的事务中运行,除非在外部事务中调用。 它们总是在单个事务中运行并且成功或失败完全。因此,不能在函数内开始或提交事务。并且不允许在事务上下文中运行的命令,如 VACUUM、CREATE DATABASE 或 CREATE INDEX CONCURRENTLY。
函数和触发过程总是在一个 由外部查询建立的事务——它们无法启动或 提交该事务,因为他们没有上下文 执行。但是,包含
EXCEPTION子句的块 有效地形成一个可以回滚的子事务,而无需 影响外部事务。
默认情况下,PL/pgSQL 函数中发生的任何错误都会中止 函数的执行,实际上是周围事务的执行 也是。您可以使用
BEGIN捕获错误并从中恢复 使用EXCEPTION子句阻止。
有例外情况,包括但不限于:
数据写入日志文件
重要提示:某些 PostgreSQL 数据类型和函数有特殊规则 关于交易行为。特别是,对一个 序列(因此是使用
serial声明的列的计数器) 对所有其他事务立即可见并且不滚动 如果进行更改的事务中止,则返回。
准备好的陈述
SQL Fiddledemo
dblink 调用(或类似的)
【讨论】:
来自Postgresql的官方文档:
在由 CALL 命令调用的过程中以及在匿名代码中 块(DO 命令),可以使用 命令 COMMIT 和 ROLLBACK。新事务开始 使用这些命令结束事务后自动执行,因此 没有单独的 START TRANSACTION 命令。 (请注意,BEGIN 和 END 在 PL/pgSQL 中有不同的含义。)
https://www.postgresql.org/docs/11/plpgsql-transactions.html
【讨论】: