如何检查 PostgreSQL 事务中的待处理操作

Posted

技术标签:

【中文标题】如何检查 PostgreSQL 事务中的待处理操作【英文标题】:How to check for pending operations in a PostgreSQL transaction 【发布时间】:2010-12-11 16:40:25 【问题描述】:

我在 PostgreSQL 上有一个会话 (SQLAlchemy),有一个活动的未提交事务。我刚刚通过 sqlalchemy.orm 或直接通过底层连接将会话传递给了一些调用树,这些调用树可能已经或可能没有发出 SQL INSERT/UPDATE/DELETE 语句。

有没有办法检查此事务中是否有任何待处理的数据修改语句? IE。提交是否会是空操作,回滚是否会丢弃某些东西?

我已经看到有人在 Oracle 中指出 v$transaction 用于同样的事情(请参阅 this SO question)。我正在寻找类似于在 PostgreSQL 上使用的东西。

【问题讨论】:

【参考方案1】:

首先检查系统视图 pg_locks。

http://www.postgresql.org/docs/8.4/interactive/view-pg-locks.html

【讨论】:

结论是 PostgreSQL 根本没有这个(相当于 Oracle 的 v$transaction),我接受你的回答作为明智的做法。 除非事务获得了任何锁,否则在 pg_locks 中找不到任何有用的东西。【参考方案2】:

考虑以下语句序列:

select txid_current();

begin;

select txid_current();

如果两个select返回的事务id相等,那么就有一个open事务。如果不是,那么就没有,(但现在是)。

如果数字不同,那么作为副作用,您将只是打开了一笔交易,您可能想要关闭该交易。

更新:事实上,正如@r2evans 指出的那样(感谢您的洞察力!),您不需要“开始” - txid_current() 将返回相同的数字,只要您正在交易中。

【讨论】:

也许你不需要begin:如果你两次连续查询select txid_current();,如果它们返回的数字与你当前在事务中的数字相同。【参考方案3】:

不,不是从数据库级别,真的。也许您可以在 sqlalchemy 级别添加一些跟踪来跟踪它?

另外,您如何定义无操作?如果您将一个值更新为与之前相同的值怎么办,这是否是空操作?从数据库的角度来看,如果它有一个,它就不会是空操作。但从应用程序的角度来看,它可能会。

【讨论】:

当然,冗余写入也是“无操作”,但我不想检测到这一点(成本大于价值)。我只想知道事务是否有任何写/删除操作,无效与否。【参考方案4】:

Since Postgres 10:

select txid_current_if_assigned();

如果当前没有交易,则返回 null。

如果发出了 Start Transaction,如果没有更新,它仍然会返回 null

【讨论】:

以上是关于如何检查 PostgreSQL 事务中的待处理操作的主要内容,如果未能解决你的问题,请参考以下文章

postgresql事务处理与并发控制

在 Redux 应用程序中的页面转换时拒绝先前路由的待处理操作

如何将更改从主分支中的待处理更改列表迁移到 perforce 中的另一个分支

如何处理通知中的待处理意图

PostgreSQL TRANSACTION(事务)

PostgreSQL TRANSACTION(事务)