如何在 postgres 中执行幻读?

How can I enforce a phantom read in postgres?

我目前正在写一篇关于不同事务隔离级别的文章,想展示脏读/不可重复读/幻读。

脏读无法显示,因为 PostgreSQL 没有 READ_UNCOMMITTED,我有一个不可重复读的例子。但是,我很难找到幻读的例子。

作为示例,我创建了这个:

CREATE TABLE balances (id varchar PRIMARY KEY, balance int);
INSERT INTO balances (id, balance) VALUES ('Alice', 40), ('Bob', 50);

然后我有两个终端(T1 和 T2)连接到数据库来执行此操作:

T1$ start transaction isolation level repeatable read;
T1$ SELECT * FROM balances WHERE balance > 10;
    id    | balance 
----------+---------
 Alice    |     40
 Bob      |     50

T2$ INSERT INTO balances (id, balance) VALUES ('Charlie', 60);
T1$ SELECT * FROM balances WHERE balance > 10;

    id    | balance 
----------+---------
 Alice    |     40
 Bob      |     50   

为什么这不会产生幻读?我认为最后一个 T1-Query 应该显示查理,但事实并非如此。我认为只有 SERIALIZABLE 事务隔离级别才会出现这种情况。 REPEATABLE READ 是否也能防止 PostgreSQL 中的幻读?

在 Postgres 12 中,REPEATABLE_READ 事务隔离级别可防止幻读 (source)。