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

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

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

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

【问题讨论】:

    标签: postgresql transactions sqlalchemy


    【解决方案1】:

    【讨论】:

    • 结论是 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

    【讨论】:

      猜你喜欢
      • 2010-11-20
      • 2011-07-29
      • 2018-02-11
      • 2014-02-02
      • 2014-11-21
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多