回答我自己的问题,因为围绕该主题似乎有很多困惑。看起来:
-- BAD! DO NOT DO THIS! --insert customer (email, count) select 'foo@example.com', 0where not exists ( select 1 from customer where email = 'foo@example.com')
对竞争条件开放。从我所能收集的资料来看,这个问题的唯一可移植的解决方案是:
- 选择一个要合并的键。这可以是主键,也可以是另一个唯一键,但是 必须 具有唯一约束。
- 尝试
insert
新的一行。您必须捕获如果该行已存在将发生的错误。 - 困难的部分结束了。在这一点上,可以确保该行存在,并且由于对它持有写锁定(由于
insert
上一步中的),因此可以保护您免受竞争条件的影响。 - 继续,
update
如果需要或使用select
它的主键。



