问题描述
我有一个带有子查询的插入查询,我想在 Postgres 数据库上运行它。但我不确定查询及其子查询是否在单个事务中运行。
我们有两个实体“configs”和“config_versions”。一个“config”可以有多个“config_versions”。 每个 'config_version' 都有一个 'rolling_version_id',它不是表的自动递增 id(主键)。 'rolling_version_id' 随 'config_id' 增加并从 1 开始,这意味着 config_id + rolling_version_id 有一个唯一的约束。我是这样解决的:
INSERT INTO config_versions(rolling_version_id,config_id,note)
VALUES (
CASE WHEN EXISTS(SELECT * FROM config_versions WHERE config_id=42)
THEN (SELECT MAX(rolling_version_id)+1 FROM config_versions WHERE config_id=42 GROUP BY config_id) ELSE 1 END,42,'SomeNote');
问题:这个查询线程是否安全/它是否在单个事务中运行?
解决方法
不确定你说的安全是什么意思,sql 事务也是原子的, 无论如何,我不确定您的查询是否运行,但您可以在此处简化它:
INSERT INTO config_versions(rolling_version_id,config_id,note)
SELECT coalesce(MAX(rolling_version_id)+1,1),42,'SomeNote'
FROM config_versions
WHERE config_id=42
dbfiddle here
,您的查询效率低下,但安全(但这与多线程无关)。
完整的 SQL 语句,包括其子查询,使用相同的数据库快照,也就是说,它们看到的数据库状态相同。