gpt4 book ai didi

postgresql - 如何捕获具有 UOW 副作用的函数的 PostgreSQL ROLLBACK?

转载 作者:行者123 更新时间:2023-11-29 13:51:13 26 4
gpt4 key购买 nike

我正在编写一个标量 plpgsql 函数,其中包含一个在数据库外部具有副作用的 C 函数。当函数被调用时,在一些任意 SQL(触发、选择、写入等)中,我希望在 PostgreSQL 工作单元 (UOW) 边界上提交或回滚副作用。我可以处理 UOW 提交,但我不知道如何“捕获”数据库 ROLLBACK 并回滚副作用。关键是我正在编写函数,但无法控制它的调用方式,即我无法“强制”将调用置于具有 EXCEPTION 处理程序的 block 中。有什么想法吗?

对于提交,我计划将 plpsql 函数插入到具有触发器“...插入后...执行过程 commit_my_side_effect()”的数据库表中,因此当提交 UOW 时,该行也会提交, AFTER INSERT 触发器触发并立即产生副作用;

到目前为止,我唯一的想法是将 txid_current() 传递给后台工作进程。然后在使用 SPI 的某些心跳上,检查 txid 是否未在运行或已提交,那么它一定已被回滚。但这似乎是一项繁重的工作。

最佳答案

从广义上讲,如果事务未提交且不再运行,则该事务被视为“回滚”;为了符合 ACID,明确的 ROLLBACK 需要在功能上与拔掉服务器上的电源线相同,因此一般来说,不会有任何与回滚相关的故意操作,您可能能够 Hook 。

回滚数据的实际删除由 vacuuming 处理,它的工作方式或多或少类似于您建议的后台工作人员:由未运行且未提交的事务编写的任何内容都可以删除。然而,除此之外还有更多,因为包含子事务(SAVEPOINT 或 PL/pgSQL EXCEPTION block )的事务可以部分回滚。换句话说,仅 txid_current() 不足以决定是否提交了更改,我不知道 Postgres 是否公开了足够的有关子事务状态的信息来让您满足这一要求。

我认为唯一明智的方法是将副作用的应用程序移动到外部进程,并在提交后触发它,一旦您知道实际提交了什么。我想到了两种方法:

  • 将您的 PL/pgSQL 函数插入到由外部进程轮询的工作队列中,或者
  • 通过 NOTIFY 将更改反馈给流程(通知仅在提交时传递,来自回滚子事务的通知将被丢弃)

通知更轻量且延迟更低(它们是异步传递的,因此不需要轮询),但不如基于表的方法健壮,因为在发生崩溃或意外事件时通知队列会被清除断开。当然,如果您希望在没有轮询缺点的情况下实现碰撞安全,则可以简单地同时执行这两种操作。

关于postgresql - 如何捕获具有 UOW 副作用的函数的 PostgreSQL ROLLBACK?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40915581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com