如何设计一个调用嵌套函数并仅在所有被调用的嵌套函数都提交时才提交的事务,例如,如果一个子函数失败则中止?

例如,此事务处理:

CREATE OR REPLACE FUNCTION unfollow(
    follower_id uuid,
    following_id uuid
)
    RETURNS void
    LANGUAGE plpgsql
    SECURITY INVOKER
AS
$$
BEGIN
        PERFORM delete_relationship(
    follower_id,
    following_id
        );
        PERFORM decrement_counter(
    following_id
            );

END;
$$;

仅当两个更新函数都成功时才应提交.当我在被调用的函数中的每个数据库操作中添加一条语句来判断前面的CRUD操作是否成功时,这是有效的,如果不成功,则引发异常.喜欢:

CREATE OR REPLACE FUNCTION delete_relationship(
    follower_id uuid,
    following_id uuid
)
    RETURNS void
    LANGUAGE plpgsql
    SECURITY INVOKER
AS
$$
BEGIN
    DELETE
    FROM
        following_profiles
    WHERE
          follower = follower_id
      AND following = following_id;

    IF NOT FOUND THEN
        ROLLBACK;
        -- Raise an exception to roll back the transaction
        RAISE EXCEPTION 'Error in unfollow_transaction: %', SQLERRM;
    END IF;
END;
$$;

如果我不引发异常,事务将提交,即使其中一个子函数失败也会提交.

有没有更聪明的方法来做这件事?如果CRUD操作失败而不每次都提到它,是否有可能使函数在默认情况下引发异常,例如,是否有方法避免编写所有异常语句?

推荐答案

未能 Select 、更新或删除与WHERE子句匹配的行并不例外.

但是,您不需要回滚任何内容.任何例外--无论是从分贝本身还是您的代码这样做.这基本上是交易的全部意义所在.要么一切正常,要么一事无成.


Additon回应下面的 comments .

影响零行并不例外,因为...这没什么不寻常的

UPDATE enquiries SET status='expired'
WHERE status='pending' AND query_date < CURRENT_DATE - 365

这是您可能每天晚上从计划任务中运行的那种查询.如果没有任何旧的未决查询,为什么要抛出异常呢?这是很正常的情况

Sql相关问答推荐

Oracle SQL中的累计总数

我可以将INSERT语句与SELECT一起使用来创建条件吗?

使用`lag()`获取上一个时间戳

每组显示一行(表1中的分组值),表2中的不同列表用逗号分隔

查找表中特定值的上次更新日期

NULL-生成的列中连接的字符串的输入

正在编写查询.我需要将订阅的时间段分为第一个订阅中包含的另一个订阅之前和之后的时间段

在WHERE EXISTS子查询中,列返回是否重要?

如何在多列上编写具有不同条件的查询?

使用CTE在SNOWFLAKE中创建临时表

每个分组最多 Select 最后 2 个值并并排显示它们

我需要在 ASP.NET C# 中获取 2 个 SQL 查询结果的平均值

SQL 多个不满足的条件失败

PostgreSQL中如何提取以特定字符开头的字符串中的所有单词?

如何 Select 一列具有最小值而另一列具有给定值的记录?

T-SQL 查询计算日期在其他列中定义的日期之间绑定的行数

SELECT 用于 Parent、Children 和 ORDER BY [Order] 列

使用 JSON_BUILD_OBJ 从 Postgres 返回 JSON

Oracle SQL 查询自行运行,但在包装到select count(*) from ()时失败

为什么这是 AND,OR with NULL 的真值表?