यह SELECT or INSERT
. की बार-बार आने वाली समस्या है , एक यूपीएसईआरटी से संबंधित (लेकिन इससे अलग)। Postgres 9.5 में नई UPSERT कार्यक्षमता अभी भी महत्वपूर्ण है।
WITH ins AS (
INSERT INTO names(name)
VALUES ('bob')
ON CONFLICT ON CONSTRAINT names_name_key DO UPDATE
SET name = NULL
WHERE FALSE -- never executed, but locks the row
RETURNING id
)
SELECT id FROM ins
UNION ALL
SELECT id FROM names
WHERE name = 'bob' -- only executed if no INSERT
LIMIT 1;
इस तरह आप वास्तव में आवश्यकता के बिना एक नया पंक्ति संस्करण नहीं लिखते हैं।
हालांकि , अभी भी दौड़ की स्थिति के लिए एक छोटा कोना मामला है . समवर्ती लेन-देन ने एक परस्पर विरोधी पंक्ति जोड़ी हो सकती है, जो अभी तक उसी कथन में दिखाई नहीं दे रही है। फिर INSERT
और SELECT
खाली आ जाओ।
एकल-पंक्ति UPSERT के लिए उचित समाधान:
- क्या किसी ऐसे फंक्शन में SELECT या INSERT है जो दौड़ की स्थिति से ग्रस्त है?
थोक UPSERT के लिए सामान्य समाधान:
- PostgreSQL में ON CONFLICT के साथ RETURNING का उपयोग कैसे करें?
समवर्ती लेखन भार के बिना
यदि समवर्ती लेखन (एक अलग सत्र से) संभव नहीं है, तो आपको पंक्ति को लॉक करने की आवश्यकता नहीं है और इसे सरल बनाया जा सकता है:
WITH ins AS (
INSERT INTO names(name)
VALUES ('bob')
ON CONFLICT ON CONSTRAINT names_name_key DO NOTHING -- no lock needed
RETURNING id
)
SELECT id FROM ins
UNION ALL
SELECT id FROM names
WHERE name = 'bob' -- only executed if no INSERT
LIMIT 1;