9

考虑在 PostgreSQL 9.1(或 9.2)中执行的以下查询:

SELECT * FROM foo WHERE bar = true

假设这是一个运行时间相当长的查询(例如,需要一分钟)。

如果在查询开始时有 500 万条记录bar = true保留,并且在另一个事务中的此查询期间,foo表中添加和删除了行,并且对于某些现有行,对bar字段进行了更新。

这会影响上面显示的选择查询的结果吗?

我知道单个事务中不同语句之间的事务隔离和可见性,但是正在运行的单个语句呢?

4

2 回答 2

10

不会。
由于 MVCC 模型,只有在查询开始时可见的元组才会在单个SELECT. 此处手册中的详细信息:

Read Committed 是 PostgreSQL 中的默认隔离级别。当事务使用此隔离级别时,SELECT 查询(没有 FOR UPDATE/SHARE 子句)只能看到查询开始之前提交的数据; 它永远不会看到未提交的数据或并发事务在查询执行期间提交的更改。实际上,SELECT 查询会在查询开始运行时看到数据库的快照。但是,SELECT 确实会看到在其自己的事务中执行的先前更新的影响,即使它们尚未提交。另请注意,如果其他事务在第一个 SELECT 执行期间提交更改,则两个连续的 SELECT 命令可以看到不同的数据,即使它们在单个事务中也是如此。

强调我的。

于 2012-08-24T13:38:27.653 回答
5

查询将是查询开始时数据的读取一致视图。在 Postgresql 中,关于多版本并发控制 (MVCC) 的文档解释了它是如何完成的(表中存在多个版本的记录)。在 Oracle 中,序列更改号 (SCN) 与修改数据的“前映像”一起使用。这是一个旧文档,Postgresql中的事务处理,其中包含“非覆盖存储管理”部分。但是看看 MVCC。

或者阅读Postgresql 文档中关于MVCC的章节

于 2012-08-24T13:38:40.417 回答