WITH values (a_name, a_area ) AS ( VALUES ('thename', 'thearea')),
t AS (SELECT name FROM area_table, values WHERE name=a_name),
i AS (INSERT INTO area_table (name, area)
SELECT a_name, a_area FROM values WHERE a_name NOT IN (SELECT name FROM t))
SELECT a_name,a_area FROM values WHERE a_name IN (SELECT name FROM t);
以上查询运行正常。我只是想知道它是否会出现并发问题,如果数据被两个或多个人同时插入它可能有任何问题或者它没问题?请帮助我对Postgres CTE和WITH声明不太了解。
答案 0 :(得分:0)
如果两个或多个人同时插入数据[可能]有任何问题[?]
是的,会有问题。在并发执行的情况下,该语句是不安全的,因为它可以引发唯一的违规错误(如果存在合适的唯一约束)或插入重复项(如果不存在唯一约束)。
这个片段:
NOT IN (SELECT name FROM t)
可以在多个会话中同时运行 。这两个会话都没有INSERT
编辑元组。即使它有,它也是未提交的,因此SELECT
不会在其快照中看到它。两个实例都将返回false
,从而执行INSERT
。
(另外,如果列可以为空,NOT IN
可能会产生意外结果,并且速度很慢。请使用NOT EXISTS
或左反连接。
在一个语句中执行所有操作 - wCTE或其他 - 不会使并发问题消失,尽管它可能会使它更难以触发它们。即使是两个简单的UPDATE
也可以进行与其并发执行相关的交互(以死锁的形式)。认为ACID的“atomacity”意味着某种语句在逻辑瞬间执行是一个常见的错误。事实并非如此。原子性属性是指一个事务要么所有更改生效,要么回滚而没有更改生效。
请参阅:How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?