Har*_*mal 12 database postgresql stored-procedures transactions relational-database
如果存储过程在中间失败,那么从SP开始的那一点的更改是否隐式回滚,或者我们是否必须编写任何显式代码以确保SP仅在数据库事务中运行?
Erw*_*ter 25
严格来说,Postgres目前(包括版本10)不具有 ANSI标准中定义的"存储过程".一切都是用"函数"完成的,它们提供了与其他RDBMS提供的存储过程相同的功能(和更多).主要区别在于交易处理.
Postgres 11最终引入了真正的存储过程:
函数在Postgres中是原子的,并且在自己的事务中自动运行,除非在外部事务中调用.它们总是在单个事务中运行,并且完全成功或失败.因此,无法在函数内开始或提交事务.并且不允许使用VACUUM
或CREATE DATABASE
不能在事务块中运行的命令.
函数和触发器过程总是在外部查询建立的事务中执行 - 它们无法启动或提交该事务,因为它们没有上下文可供执行.但是,包含
CREATE INDEX CONCURRENTLY
子句的块有效地形成了一个子事务,可以是回滚而不影响外部交易.
默认情况下,PL/pgSQL函数中发生的任何错误都会中止函数的执行,也会中止周围事务的执行.您可以使用
EXCEPTION
带有BEGIN
子句的块来捕获错误并从中恢复.
有特殊例外,包括但不限于:
重要:一些PostgreSQL数据类型和函数有关于事务行为的特殊规则.特别是,对序列(以及因此声明的列的计数器
EXCEPTION
)所做的更改对所有其他事务立即可见,并且如果进行更改的事务中止,则不会回滚.
准备好的陈述
dblink调用(或类似)
如果您使用的是 Postgres 14 程序,如下所示:
CREATE OR REPLACE PROCEDURE test_error(schema_name text)
LANGUAGE plpgsql
AS
$$
declare
<declare any vars that you need>
BEGIN
<do your thing>
END
$$;
Run Code Online (Sandbox Code Playgroud)
出于所有实际目的,在BEGIN
和END
块之间编写的代码在单个事务中执行。因此,如果块中的任何语句失败,则所有先前的语句将自动回滚。您不需要显式编写任何回滚代码。
但是,在某些特殊情况下,人们可以对何时启动/提交/回滚事务进行细粒度控制。有关详细信息,请参阅:https://www.postgresql.org/docs/current/plpgsql-transactions.html 。
归档时间: |
|
查看次数: |
6719 次 |
最近记录: |