我有一些微服务(几乎)系统,其中每个程序都有自己的端口。此外,并非系统中的所有端口都可用。为简单起见,我决定在 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/