每个 WITH 查询是否算作一个读提交事务中的单独命令?

Does each WITH query count as a separate command in a read-committed transaction?

假设我有以下简单代码:

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

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

我的问题是:在示例代码中,这两个不同的 select 是算作单个已提交读取命令,还是每个 select 都是独立的,从而使两者都成为可能以(理论上)看到不同的行?

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 的评论。

从这里开始 WITH:

The primary query and the WITH queries are all (notionally) executed at the same time. This implies that the effects of a data-modifying statement in WITH cannot be seen from other parts of the query, other than by reading its RETURNING output. If two such data-modifying statements attempt to modify the same row, the results are unspecified.

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

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