【问题标题】:Does each WITH query count as a separate command in a read-committed transaction?是否每个 WITH 查询都算作读取提交事务中的单独命令?
【发布时间】:2021-11-08 14:57:55
【问题描述】:

假设我有以下简单的代码:

BEGIN;
WITH foo AS (SELECT * FROM t1),
     bar AS (SELECT * FROM t1)
SELECT * FROM foo, bar;
COMMIT;

隔离级别为by default, READ-COMMITTED。这当然意味着如果你有两个单独的选择,你可以(理论上)有不可重复的读取。

我的问题是:在示例代码中,这两个不同的选择是否算作一个已提交的读取命令,还是每个选择都单独进行,从而(理论上)可以看到不同的行?

【问题讨论】:

  • 我已经尝试并未能在official dox 中找到答案。 “阅读 dox”的答案是完全有效的——只要你包含一个链接供我阅读。谢谢!
  • 它只运行最后一个 Select 语句,因为您实际上并没有在此查询中使用 CTE。
  • 我想我将不得不更新我的“琐碎”示例

标签: postgresql transactions


【解决方案1】:

从这里WITH:

主查询和 WITH 查询都(理论上)同时执行。这意味着 WITH 中的数据修改语句的效果无法从查询的其他部分看到,除非通过读取其 RETURNING 输出。如果两个这样的数据修改语句尝试修改同一行,则结果未指定。

如果您想了解更多详细信息,请参阅CTE。在本节中,它贯穿了各种场景。

【讨论】:

  • 我认为这已经解决了。我绝对没有读到这里,谢谢。
【解决方案2】:

所有三个扫描都是使用查询的快照执行的,因此它们都可以保证看到数据库的相同状态。

【讨论】:

    【解决方案3】:

    EXPLAIN ANALYZE 应用于您的示例提供如下内容:

    Seq Scan on t1 (cost=0.00..71.21 rows=621 width=233) (actual time=0.015..0.102 rows=621 loops=1)"
    Planning Time: 0.078 ms
    Execution Time: 0.132 ms
    

    这证实了@Anton Grig 的评论。

    【讨论】:

      猜你喜欢
      • 2020-01-19
      • 2019-11-17
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      • 2014-07-19
      • 1970-01-01
      • 2019-06-01
      相关资源
      最近更新 更多