sql >> Databáze >  >> RDS >> PostgreSQL

Jak se vyhnout konfliktním podmínkám při použití metody find_or_create DBIx::Class::ResultSet?

Ne, dokumentace je nesprávná. Použití samotné transakce ne vyhnout se tomuto problému. Zaručuje pouze, že celá transakce bude vrácena zpět, pokud by došlo k výjimce – takže v databázi nebude přetrvávat žádný nekonzistentní stav.

Chcete-li se vyhnout tento problém musíte uzamknout tabulku - uvnitř transakce, protože všechny zámky jsou uvolněny na konci transakce. Něco jako:

BEGIN;
LOCK TABLE mytbl IN SHARE MODE;

-- do your find_or_create here

COMMIT;

Ale to není kouzelný lék na všechno. Může se stát problémem s výkonem a může dojít k zablokování (souběžné transakce se vzájemně snaží uzamknout zdroje, které ten druhý již zamkl). PostgreSQL takový stav detekuje a zruší všechny konkurenční transakce kromě jedné. Musíte být připraveni zopakovat operaci při selhání.

Příručka PostgreSQL o zámcích.

Pokud nemáte mnoho souběžnosti, můžete problém také ignorovat. Časový úsek je velmi malý, takže se to skutečně stane jen velmi zřídka. Pokud zachytíte chybu porušení duplicitního klíče, která nepoškodí, pak jste to také zakryli.



  1. Příkaz případu v MySQL

  2. Jak nastavit „5 dní“ (interval data a času) v jdbc pro PostgreSQL?

  3. Jak RAND() funguje v MariaDB

  4. Mapování Doctrine 2 odkazující na jedinečný klíč