【发布时间】:2014-04-23 12:50:24
【问题描述】:
如果totals 表中不存在相应的行,我有这个查询尝试将行添加到balances 表中。查询使用 PostgreSQL 上的默认隔离级别在事务中运行。
INSERT INTO balances (account_id, currency, amount)
SELECT t.account_id, t.currency, 0
FROM balances AS b
RIGHT OUTER JOIN totals USING (account_id, currency) AS t
WHERE b.id IS NULL
我对@987654326@ 有一个UNIQUE 约束。我担心如果多个会话同时执行此查询,我会陷入一种竞争状况,这将导致重复的键错误。我见过很多关于这个主题的问题,但它们似乎都涉及子查询、多个查询或 pgSQL 函数。
由于我没有在我的查询中使用任何这些,它是否不受竞争条件的影响?如果不是,我该如何解决?
【问题讨论】:
-
是的,您仍然可以得到重复键错误。出于同样的原因,当两个会话使用相同的
values子句运行相同的insert语句时,您可以获得它。该语句在运行时会看到数据库的一致状态,因此即使在语句运行时提交了新行,它也不会看到任何新行。 -
在重复键违规的情况下循环的 plpgsql 函数可以处理服务器端和默认隔离级别的竞争条件,这是 安全 一个典型的 最便宜的。该应用程序不必费心重试:stackoverflow.com/questions/15939902/…
标签: sql postgresql race-condition