Nee, de documentatie is onjuist. Het alleen gebruiken van een transactie doet niet vermijd dit probleem. Het garandeert alleen dat de hele transactie wordt teruggedraaid als zich een uitzondering voordoet - zodat er geen inconsistente status in de database wordt gehandhaafd.
Om vermijden dit probleem moet u de tafel vergrendelen - binnen een transactie, omdat alle vergrendelingen aan het einde van een transactie worden vrijgegeven. Iets als:
BEGIN;
LOCK TABLE mytbl IN SHARE MODE;
-- do your find_or_create here
COMMIT;
Maar dat is niet een magische remedie voor alles. Het kan een prestatieprobleem worden en er kunnen deadlocks zijn (gelijktijdige transacties die wederzijds middelen proberen te vergrendelen die de andere al heeft vergrendeld). PostgreSQL zal een dergelijke voorwaarde detecteren en alle concurrerende transacties op één na annuleren. U moet voorbereid zijn om de bewerking opnieuw te proberen als deze mislukt.
De PostgreSQL-handleiding over sloten.
Als je niet veel concurrency hebt, kun je het probleem ook gewoon negeren. Het tijdslot is erg klein, dus het gebeurt maar heel zelden echt. Als je de dubbele sleutelovertredingsfout opmerkt, wat geen kwaad kan, dan heb je dit ook gedekt.