INSERT INTO with Subqueries 是否作为单个事务运行线程安全?

问题描述

我有一个带有子查询的插入查询,我想在 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 语句,包括其子查询,使用相同的数据库快照,也就是说,它们看到的数据库状态相同。