Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    505

    mysql - dubbio su atomicità operazione update

    salve. vorrei avere una delucidazione su un dubbio che mi salta in mente riguardo a una condizione di race condition in fase di update all'interno del database.

    supponiamo di avere questa tabella chiamata tracklist con questi record :

    id block name

    1 0 paolo
    2 0 marco
    3 0 luca

    se io eseguo questa query in contemporanea su due thread distinti (due richieste nello stesso momento):

    $update = mysql_query("UPDATE tracklist SET block = '1' WHERE name='marco' AND block='0'",$mydb);

    il primo che arriva fà il lock sul record con id 2, e lo aggiorna. l'altra richiesta, contemporanemante, come si comporta?

    1-arriva all'id 1 e la scarta (nome è paolo non marco), vede che id2 è bloccata, aspetta, la seleziona e (non rispettando più la regola del where, essendo ora block = 1) la scarta e và avanti

    2-arriva all'id 1 e la scarta, (anche quì nome è paolo non marco), seleziona il record 2 e appena il thread che l'aveva bloccata la "sblocca" fà l'update del campo

    3-nessuna delle 2

    se qualcuno ha idea, mi farebbe un favore! grazie mille

  2. #2
    Utente di HTML.it L'avatar di Ceras
    Registrato dal
    Oct 2009
    Messaggi
    141

    Re: mysql - dubbio su atomicità operazione update

    Originariamente inviato da markzzz
    salve. vorrei avere una delucidazione su un dubbio che mi salta in mente riguardo a una condizione di race condition in fase di update all'interno del database.

    supponiamo di avere questa tabella chiamata tracklist con questi record :

    id block name

    1 0 paolo
    2 0 marco
    3 0 luca

    se io eseguo questa query in contemporanea su due thread distinti (due richieste nello stesso momento):

    $update = mysql_query("UPDATE tracklist SET block = '1' WHERE name='marco' AND block='0'",$mydb);

    il primo che arriva fà il lock sul record con id 2, e lo aggiorna. l'altra richiesta, contemporanemante, come si comporta?

    1-arriva all'id 1 e la scarta (nome è paolo non marco), vede che id2 è bloccata, aspetta, la seleziona e (non rispettando più la regola del where, essendo ora block = 1) la scarta e và avanti

    2-arriva all'id 1 e la scarta, (anche quì nome è paolo non marco), seleziona il record 2 e appena il thread che l'aveva bloccata la "sblocca" fà l'update del campo

    3-nessuna delle 2

    se qualcuno ha idea, mi farebbe un favore! grazie mille

    Guarda, che io sappia tutte le query vengono serializzate, e quindi viste come atomiche. Il concetto è analogo a quello dei lock semplici,

    - se tutti gli oggetti non sono occupati acquisisci il lock, fai la query e rilasci il lock
    - se almeno un oggetto è occupato attendi finché non viene rilasciato il lock

    Il semplice risultato che porta questa sincronizzazione è quello di eseguire sempre e comunque una query alla volta (se collidono), quindi ci saranno effettivamente 2 query eseguite in serie:

    $update = mysql_query("UPDATE tracklist SET block = '1' WHERE name='marco' AND block='0'",$mydb);
    $update = mysql_query("UPDATE tracklist SET block = '1' WHERE name='marco' AND block='0'",$mydb);

    La prima query (invocata dal primo thread schedulato) esegue la modifica, quindi si avrà

    1 0 paolo
    2 1 marco
    3 0 luca

    La seconda query non trova nessuna riga che rispetta il WHERE, quindi non esegue alcuna modifica.

    Per maggiori info potresti dare un'occhiata al MySQL Reference Manual, nella sezione "synchronization"

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    505
    ah, scusa del ritardo, e grazie mille per la delucidazione.

    ora, quello che mi servirebbe, è che la query di update (oltre a fare l'update vero e propio) mi tornasse un valore di ritorno. es : quando riesce a fare l'update torna 1. se non fà l'update di nulla torna 0. credo sia possibile utilizzando dei costrutti if/else all'interno della query, ma non avrei idea di dove partire.

    qualcuno potrebbe consigliarmi qualcosa?

    grazie per l'aiuto.

  4. #4
    Utente di HTML.it L'avatar di Ceras
    Registrato dal
    Oct 2009
    Messaggi
    141
    Originariamente inviato da markzzz
    ah, scusa del ritardo, e grazie mille per la delucidazione.

    ora, quello che mi servirebbe, è che la query di update (oltre a fare l'update vero e propio) mi tornasse un valore di ritorno. es : quando riesce a fare l'update torna 1. se non fà l'update di nulla torna 0. credo sia possibile utilizzando dei costrutti if/else all'interno della query, ma non avrei idea di dove partire.

    qualcuno potrebbe consigliarmi qualcosa?

    grazie per l'aiuto.
    L'update fa proprio questo
    Oltre a fare la modifica, ritorna il numero di righe che sono state modificate.

    Direttamente dal mysql reference manual:

    UPDATE returns the number of rows that were actually changed. The mysql_info() C API function returns the number of rows that were matched and updated and the number of warnings that occurred during the UPDATE.

    Quindi dopo la query ti basta controllare il valore mysql_info()

    http://dev.mysql.com/doc/refman/5.0/en/update.html

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    505
    intendi mysql_info($update) ?

  6. #6
    Utente di HTML.it L'avatar di Ceras
    Registrato dal
    Oct 2009
    Messaggi
    141
    no, solo mysql_info()

    http://www.php.net/manual/en/function.mysql-info.php

    Però ho appena visto che mysql_info dà molte più informazioni, per estrarre il numero di righe modificate si dovrebbe ricorrere a funzioni stringa.

    Ho appena trovato la funzione ad oc:
    mysql_num_rows()

    http://www.php.net/manual/en/functio...l-num-rows.php

    Dopo una query mysql_num_rows() ritorna direttamente il numero di righe trovate/modificate.
    Puoi usarlo senza parametri, in questo caso si riferisce all'ultima query eseguita. Non c'è conflitto per utilizzi multipli, in quanto l'ultima query eseguita si riferisce solo alle connessioni del thread corrente.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    505
    "This command is only valid for statements like SELECT or SHOW that return an actual result set. To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use mysql_affected_rows(). "

    mi sà che devo usare quest'ultimo per l'update. Grande, non sapevo dell'esistenza di questa funzioncina in PHP.

    grazie ancora per la delucidazione, ora dovrei avere tutto quello che mi serve :=)

  8. #8
    Utente di HTML.it L'avatar di Ceras
    Registrato dal
    Oct 2009
    Messaggi
    141
    Originariamente inviato da markzzz
    "This command is only valid for statements like SELECT or SHOW that return an actual result set. To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use mysql_affected_rows(). "

    mi sà che devo usare quest'ultimo per l'update. Grande, non sapevo dell'esistenza di questa funzioncina in PHP.

    grazie ancora per la delucidazione, ora dovrei avere tutto quello che mi serve :=)
    Nemmeno io ne sapevo nulla, finora non mi è mai servita...
    Abbiamo imparato una cosa nuova entrambi!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.