sql >> Database >  >> RDS >> PostgreSQL

Hoe kan ik race-omstandigheden vermijden bij gebruik van de methode find_or_create van DBIx::Class::ResultSet?

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.



  1. Zoek een woordgroep die eindigt op een voorvoegsel met zoeken in volledige tekst

  2. Tabellen en kolommen neerzetten met SQL

  3. Hoe gebruik je een BIGINT als een automatisch oplopende primaire sleutel in Laravel 4

  4. Hoe efficiënt een kolom BIJWERKEN in een grote PostgreSQL-tabel met Python / psycopg2?