PostgreSQL函数和事务(含BEGIN)

5

我对PostgreSQL函数和事务的工作原理有一些问题。

目前我的函数如下:

CREATE OR REPLACE FUNCTION test_function(some_id character varying)
    RETURNS character varying AS
$BODY$
BEGIN
    S1;
    S2;
    S3;
    .
    .
    Sn;
RETURN some_id;
END; $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

这些语句可以是基于some_idINSERTUPDATE或普通的SELECT查询。根据我从PostgreSQL 文档中了解到的,该函数中的所有语句都将作为单个事务执行,并在最后提交。
我的问题是:
  1. 如果假设 S1 成功但 S2 失败,那么 S1 会被提交吗?
  2. 我的理解是,在 BEGIN 后的所有语句都将作为单个事务执行,这正确吗?
  3. 如果在 END 前没有显式的 COMMIT,并且所有语句都成功,那么无论自动提交是开启还是关闭,事务是否会被提交?
  4. 假设 S1、S2、S3 都是 INSERT 语句。 S1S2 成功,但 S3 失败,如果没有显式的 ROLLBACK 语句,那么 S1、S2 中的插入操作是否会被撤销?

谢谢!


可能是重复的问题:PostgreSQL 函数是否具有事务性? - khoroshevj
这里的 BEGINEND 仅用于将语句分组在函数中,它们不会开始或结束事务。 - khoroshevj
1个回答

5

按编号回答:

  1. 不可以;如果 S2 失败,整个事务将被中止并且只能回滚。

  2. 可能有误解。开始事务的 SQL 语句 BEGIN 和开始 PL/pgSQL 块的 BEGIN 是两个完全不同的东西。后者不会开启事务。

    如果没有明确的 SQL 命令 BEGIN,每个语句都在自己的事务中运行(“自动提交”)。

    函数中的所有语句都在单个事务中执行。

  3. 在一个函数中不可以使用 COMMIT(或 ROLLBACK)。

  4. 可以。这和问题1是同样的问题,只是相反的情况。


请确认您对第4条的回答:“是的”,在没有显式“ROLLBACK”的情况下,由S1,S2插入的行将被撤销,正确吗? - pranav3688
这就是我的意思。即使您尝试提交事务,它也会被回滚(因为它已中止)。 - Laurenz Albe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接