sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur undviker man tävlingsförhållanden när man använder metoden find_or_create i DBIx::Class::ResultSet?

Nej, dokumentationen är felaktig. Att använda enbart en transaktion inte undvika detta problem. Det garanterar bara att hela transaktionen rullas tillbaka om ett undantag skulle inträffa - så att inget inkonsekvent tillstånd kommer att kvarstå i databasen.

Att undvika detta problem måste du låsa bordet - inne i en transaktion, eftersom alla lås släpps i slutet av en transaktion. Något i stil med:

BEGIN;
LOCK TABLE mytbl IN SHARE MODE;

-- do your find_or_create here

COMMIT;

Men det är inte ett magiskt botemedel mot allt. Det kan bli ett prestandaproblem och det kan finnas dödlägen (samtidiga transaktioner som ömsesidigt försöker låsa resurser som den andra redan har låst). PostgreSQL kommer att upptäcka ett sådant tillstånd och avbryta alla utom en av de konkurrerande transaktionerna. Du måste vara beredd att försöka igen vid misslyckande.

PostgreSQL-manualen om lås.

Om du inte har mycket samtidighet kan du också bara ignorera problemet. Tidsluckan är väldigt liten så det händer bara väldigt sällan. Om du upptäcker felet med dubblettnyckeln, vilket inte skadar, har du täckt detta också.



  1. EFTER LOGON(Oracle) trigger i PostgreSQL med tillägg – login_hook

  2. Dela upp kommaseparerade värden för en kolumn i rad genom Oracle SQL-fråga

  3. JDBC automatiska fråga visade sig vara mycket långsam

  4. Trunkera alla tabeller i en databas i SQL Server - SQL Server / TSQL Tutorial Del 55