postgres 中 READ_COMMITED 的 select 更新是原子的吗?

Is update by select atomic for READ_COMMITED in postgres?

以下查询在 READ_COMMITED 事务中是原子的吗?

update my_table
 set
   owner = ?,
 where id = (
   select id from my_table
   where owner is null
   limit 1
 ) returning *

我 运行 在本地 postgres 实例上测试,它似乎是原子的,但情况总是如此吗?

READ COMMITTED 隔离级别中的每个 SQL 语句都会获取数据库的快照,因此它及其所有子查询都会看到一致的数据库版本。

但是您无法避免“丢失更新”:并发事务可能会在语句开始和更新行之间修改一行,因此可能是该行实际上是updated 不再将 owner 设置为 NULL。

如果您需要避免这种情况,请在子查询中添加一个 FOR UPDATE 子句。