2

I have a relation y(k, v) where k is a key. Having concurrent connections on the database, I run on each of them:

INSERT INTO y 
     SELECT 'k1', 'v1' WHERE NOT EXISTS (SELECT 1 FROM y WHERE k = 'k1');

sometimes I get the following error:

ERROR: duplicate key value violates unique constraint "y_pk"

Why does it happen? Can it be avoided?

Evgeny
  • 2,121
  • 1
  • 20
  • 31

2 Answers2

1

The issue here is that if this query runs in two different connections at the same time then NOT EXISTS condition true for BOTH (it's tested before insert) and then BOTH connections INSERT the same value. You need a table lock or try to use this script:

BEGIN
    INSERT INTO Y(k,v) VALUES ('k1', 'v1');
    EXCEPTION WHEN unique_violation THEN
END;

Also read this similar topic: SO:How do I do an UPSERT...

Community
  • 1
  • 1
valex
  • 23,966
  • 7
  • 43
  • 60
0

As of PostgreSQL 9.5, UPSERTS are natively suported, and would solve this use case.

Jeff Widman
  • 22,014
  • 12
  • 72
  • 88