sql - 嵌套 SQL 查询是原子的吗?

标签 sql postgresql atomic

我有一些微服务(几乎)系统,其中每个程序都有自己的端口。此外,并非系统中的所有端口都可用。为简单起见,我决定在 PostgreSQL 的表中保留空闲端口列表。因此,我有这张表:

service | port
-------------------
sm_srv  | 5600
null    | 5601
...

分别,如果service列中的值为null,则该端口空闲,否则端口繁忙。 然而,从逻辑上讲,如果您首先选择所有空闲端口,然后占用其中一个端口,则该操作将变得非原子。这可能会导致两个服务尝试占用同一端口的情况。

我正在尝试使此操作原子化。为此,我决定不进行选择,而是立即进行更新。然而,在这里我面临着 SQL 知识的缺乏,并且在互联网上找不到关于这个主题的任何内容。我的最终要求:

UPDATE table 
  SET service='asd' 
WHERE port IN (SELECT port FROM table WHERE service IS NULL LIMIT 1)
RETURNING port;

问题:这样的操作是原子的吗?或者也许我可以以某种方式让我需要的东西变得更容易?

最佳答案

您应该编写子查询,以便它锁定已找到的行以防止并发修改:

UPDATE services                                      
   SET service='asd'
WHERE port IN (SELECT port
               FROM services
               WHERE service IS NULL
               FOR NO KEY UPDATE SKIP LOCKED
               LIMIT 1)
RETURNING port;

SKIP LOCKED 导致查询忽略锁定的行,而不是在锁后面等待。

关于sql - 嵌套 SQL 查询是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66006278/

相关文章:

mysql - GROUP BY 仅具有不同值的同一字段

SQL SUM 表达式和锁

sql - 更改 View 中使用的 PostgreSQL 列

max - OpenCL 中 float 的原子最大值

c++ - num++ 可以是 'int num' 的原子吗?

php - 我怎样才能使这个 SQL 查询最有效?

sql - 在 SELECT * 中仅使用一次连接列

sql - 仅备份 SQL 架构?

postgresql - 只在内存中运行 PostgreSQL

c - `atomic_compare_exchange_strong_explicit()` -- 当不相等时,`success` 和 `failure` 参数的各种组合会做什么?