2011-02-06 19 views
5

nei miei ceppi hoptoad farò periodicamente vedereTransient Mysql :: Errore: voce duplicata su un sito ad alto traffico - qualche idea?

Mysql::Error: Duplicate entry 'XXXX' for key 'YYY'

Questo accade per la maggior parte dei miei modelli, circa 6 in tutto, e vedrò questo errore una volta ogni paio d'ore su un sito che fa circa 5k richieste/minuto secondo a newrelic.

Sto facendo un ActiveRecord.find_or_initialize_by in ognuno di questi casi. È possibile, ma improbabile, che questo provenga da un client sul campo che esegue due post simultanei degli stessi dati, poiché si tratta di client mobili e il codepath non si presta realmente a questo (ovvero, non si tratta di un clic del client un pulsante di invio due volte rapidamente).

C'è un problema noto con find_or_initialize_by? E 'possibile che la mia istanza mysql (Amazon RDS) sia ogni tanto appena sfaldata (anche se mi aspetterei di sollevare un'eccezione in quel caso e non restituire dati) ...

Inoltre, c'è un modo migliore inserire record? Se il record esiste, generalmente aggiorno solo il suo campo updated_at.

Grazie!

risposta

1

È probabile che ciò si verifichi perché "verifica validità e quindi inserimento" non è un'operazione atomica. Non c'è alcuna garanzia che qualcun altro non possa inserire una riga con lo stesso valore per una colonna unica tra il controllo di validità e l'inserimento.

Il official docs menziona questo, ma solo di passaggio, e in realtà non lo spiegano molto bene. Rails Warts ha una pagina molto migliore sul problema.

E come sembra che tu stia supportando la condizione di unicità con un indice univoco nel tuo DB, stai già facendo tutto il possibile per impedirlo sul lato DB. E non sono sicuro che se find_or_initialize_by/ON DUPLICATE KEY UPDATE sia una buona idea o meno - dipende da ciò che i tuoi utenti stanno modificando, e dalle conseguenze sulla sicurezza di loro che modificano qualcosa che non necessariamente intendono.

Spero che questo aiuti!

+0

Grazie per le informazioni .... probabilmente hai ragione, immagino sia teoricamente possibile che se c'è una latenza in una delle mie operazioni DB e un utente ripete in qualche modo un'azione, potrei attivare questo comportamento. Non lo vedo così spesso almeno (una volta ogni poche ore sembra fare migliaia di richieste/min). Ho letto il post sul blog di Rails Warts, sto facendo quello che lui e voi suggerite (sostenendolo con un controllo di validità del DB), quindi suppongo che sia buono come adesso. – esilver

0

Ho questo sito sinograms.com. Sono uno schermo che spaventa i siti di notizie per classificare i caratteri cinesi attraverso la frequenza e ho trovato la stessa roba con cui sono venuta fuori.

Ho attraversato molte fasi. Quello attuale è solo l'ultimo test e ha solo pochi milioni di indici. I duplicati sembrano venire rapidamente; lo so perché trovo solo duplicati di caratteri cinesi che sono molto comuni o indicizzati di frequente in altre parole.

+0

Sembra che tu non abbia ancora trovato una soluzione o una causa? E per essere chiari, stai utilizzando un'applicazione ruby ​​con ActiveRecord, giusto? FWIW Sto eseguendo un'applicazione ruby ​​con sinatra, non con le rotaie. – esilver

+0

Rotaie e AR. Stanno usando la stessa gemma, giusto? quindi dovrebbe essere correlato. – s84

Problemi correlati