"duplicate key value violates unique constraint" 尽管存在检查

"duplicate key value violates unique constraint" despite existence check

在 PostgreSQL 9.4 上。

我很惊讶地在我们的服务器日志中看到了这个错误,指出了 pl/pgsql 函数中的唯一语句:

CREATE OR REPLACE FUNCTION my_upsert(
    intype text,
    invalue text)
  RETURNS void AS
$BODY$
BEGIN

  WITH upsert AS
  (
    UPDATE mytable
      SET count = count + 1
    WHERE type = inType
      AND value = inValue
    RETURNING *
  )
  INSERT INTO mytable
  (
    value,
    type
  )
  SELECT inValue, inType WHERE NOT EXISTS (SELECT * FROM upsert);

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

除非升级到 9.5 以便我们可以使用内置的 upsert 功能,否则这样的单个语句怎么可能会以这种方式失败? (这可以避免吗?)

https://www.postgresql.org/message-id/8316.1296788047%40sss.pgh.pa.us

Re: isn't "insert into where not exists" atomic?

No, it isn't: it

will fail in the presence of other transactions doing the same thing... >

AFAIR the basic alternatives are insert -> exception -> update or taking a lock at the table level

(引用非常不准确 - 强烈建议阅读线程)

如果我正确理解 Toms 指令,在 9.5 upsert 之前,唯一的选择是插入,如果异常更新或其他...