Postgres 'if not exists' does not work because the sequence exists

I have several counters in the application that I create, as I try to get them to be dynamically created by the application as needed.

For a simplified example, if someone enters a word into a script, he should return the number of times that word was entered earlier. Here is an sql example that can be executed if they typed an example word.

CREATE SEQUENCE IF NOT EXISTS example START WITH 1;
SELECT nextval('example')

This will return 1on first start, 2second time, etc.

The problem is that 2 people press a button at the same time. First, note that in my application there are much more than just these statements, so the likelihood of their overlapping is much more important than if that was all that happened.

1> BEGIN;
2> BEGIN;
1> CREATE SEQUENCE IF NOT EXISTS example START WITH 1;
2> CREATE SEQUENCE IF NOT EXISTS example START WITH 1; -- is blocked by previous statement
1> SELECT nextval('example')  -- returns 1 to user.
1> COMMIT;  -- unblocks second connection
2> ERROR:  duplicate key value violates unique constraint 
   "pg_type_typname_nsp_index"
   DETAIL:  Key (typname, typnamespace)=(example, 109649) already exists. 

, " " "", , , , . , , , , .

, IF NOT EXISTS postgres, , , ?

EDIT: , , , . , , , (, , )

+4
2

. , , , , , - . , , . . , ( nextval) , , . , - , . , . , . , (, ), . , , .

, , ; "". - :

CREATE TABLE word_frequency (
    word text NOT NULL UNIQUE,
    frequency integer NOT NULL
);

, , , , .

. , . , ( "UPSERT" postgres 9.5+):

INSERT INTO word_frequency(word,frequency)
VALUES ('foo',1)
ON CONFLICT (word)
DO UPDATE
SET frequency = word_frequency.frequency + excluded.frequency
RETURNING frequency;

word_frequency 1, , 1. , , ? :

client 1          client 2
--------          --------
BEGIN
                  BEGIN
UPSERT ('foo',1)
                  UPSERT ('foo',1) <====
COMMIT
                  COMMIT

, , 2 foo ( ), , . 1 , 2 - . , . , postgresql , .

+4

EDIT: , , . , , , , (, , )

, , , , . , 100 000 , ( , ), , .

, . ( DDL ) .

DDL .

+2

Source: https://habr.com/ru/post/1654081/


All Articles