Postgres read committed 不会重新读取更新的行

Postgres read commited doesn't re read updated row

美好的一天。我在 postgres 中使用 READ COMMITTED 隔离级别,发现不符合官方文档的奇怪行为。 假设我有一个 table account(id int,name text,amount int) 和两行。

test> select * from account;                       
-[ RECORD 1 ]-------------------------
id     | 1
name   | Bob
amount | 800
-[ RECORD 2 ]-------------------------
id     | 2
name   | Bob
amount | 200

现在我开始两个 READ COMMITTED 事务。第一个执行以下查询

UPDATE account set amount = 100 where id = 2; -- 1

然后第二个执行此查询

 UPDATE account set amount = amount+50 --2
  where name in 
      (select DISTINCT name from account group by
      name having sum(amount)>=1000); 

现在它被锁定,因为第一个事务还没有提交。所以第二笔交易想要给每个总金额大于或等于1000的账户加50。因为Bob有两个账户(800+200)那么它应该给每个账户加50。但是,现在第一个事务已提交 COMMIT; --1,现在 Bob 总共有 900 个,根据 Documentation 读取已提交的事务将

The search condition of the command (the WHERE clause) is re-evaluated to see if the updated version of the row still matches the search condition. If so, the second updater proceeds with its operation using the updated version of the row

据我了解,第二笔交易将重新评估 where 条件并跳过 Bob 的帐户。但是,当提交第二个事务时,最后的行看起来像这样

id     | 1                                                                                            │
name   | Bob                                                                                          │
amount | 850                                                                                          │
-[ RECORD 3 ]-------------------------                                                                │
id     | 2                                                                                            │
name   | Bob                                                                                          │
amount | 150 

这意味着第二个事务没有重新评估搜索条件并应用更新到行,即使它们不符合条件。为什么会这样。我错过了文档中的某些内容吗?

第一个事务中的 UPDATE 会阻塞第二个查询中的 UPDATE,但 不会 该查询中的子查询。 subselect已经完成,sum已经确定为1000,所以UPDATE被执行,that被阻塞。当锁消失时,子查询不会重新求值。

您从文档中引用的段落是关于 SELECT ... FOR UPDATE(或 FOR SHARE)的,您没有使用它。它不能在您的示例中使用,因为它在使用聚合函数或分组的查询中没有意义。