Molteplici chiamate di aggiornamento MySQL al secondo, alcune di esse possono essere "perse"?

1

Ho una domanda semplice, penso che non sia un grosso problema, ma mi piacerebbe comunque chiederlo come se mi stesse impazzendo per i 2 giorni passati.

E se avessi un sondaggio in cui invece di inserire risposte a una tabella MySQL una per riga, sarebbe sufficiente cambiare la quantità di voti che la risposta ha ottenuto in fila con i dati del sondaggio?

Quindi in pratica il mio codice chiamerebbe solo UPDATE polls SET optionX=optionX+1 WHERE id='$poll_id' invece di INSERT INTO poll_votes (option, ip, poll) VALUES ('X', '$user_ip', '$poll_id') - questa è la versione semplificata, ma la base è la stessa.

La mia domanda è, cosa succede se 1.000 persone invieranno la loro risposta allo stesso tempo. C'è una remota possibilità che il server prenda dati da MySQL dove optionX non è stata ancora aggiornata dalla precedente chiamata e, come la precedente chiamata (utente) lo aggiorna, allora la prima ne sovrascriverà, praticamente perdendo quel voto?

TL; DR: può succedere?

  1. Utente 1 invia il voto per l'opzione 4
  2. Il PHP scarica i dati da MySQL dove l'Opzione 4 ha 49 voti
  3. L'utente 2 invia il voto per l'opzione 4
  4. Il PHP scarica i dati da MySQL dove l'Opzione 4 ha ancora 49 voti
  5. PHP termina l'aggiornamento della richiesta e imposta MySQL per l'opzione 4 per avere 50 voti
  6. PHP Termina l'aggiornamento della seconda richiesta e imposta l'opzione per avere 50 voti anziché 51

La preoccupazione principale per me è che sto memorizzando tutte le opzioni come un array in una cella, così posso permettere agli utenti di avere sondaggi stupidamente lunghi senza la necessità di avere una struttura estremamente complessa della tabella MySQL.

Penso che le probabilità siano davvero ridotte, ma non sono sicuro che ciò possa accadere o se ci sono alcune sicurezze per tali cose.

    
posta MiChAeLoKGB 05.06.2015 - 01:24
fonte

1 risposta

1

Nessun ACID-compatibile database causerà un errore o dati errati in questa situazione a meno che provi attivamente a lavorare contro di esso esplicitamente scherzando con i suggerimenti di blocco o altre cose strane che la maggior parte delle persone non fa.

MySQL è compatibile con ACID per impostazione predefinita. Non ho controllato ultimamente, ma potresti essere in grado di utilizzare tipi di tabelle antiche che non lo garantiscono. Finché si utilizza una versione di MySQL non più vecchia di dieci anni e non si punta una pistola al piede e si preme il grilletto, non si avrà accidentalmente un tipo di tabella non conforme a ACID.

A : Atomicità. Un'operazione ha esito positivo o non riesce nel suo complesso. O l'incremento funziona come un'unità o fallisce come unità.

I : isolamento. I thread non possono vedere risultati "parziali" di altri thread.

L'atomicità garantisce che l'istruzione non possa fallire a metà strada (anche l'onsistenza C aiuta qui, ad esempio se si verifica un arresto anomalo mentre SQL sta aggiornando una tabella). L'isolamento garantisce che non hai il classico esempio di threading di interleaving di due incrementi (che descrivi nella tua domanda).

    
risposta data 05.06.2015 - 01:39
fonte

Leggi altre domande sui tag