Laboratorio di Sistemi Informativi
Soluzioni esercizi - Validazione dati
Esercizio 1
Sia data la tabella contatore
, all'interno del database test
, creata e inzializzata con i seguenti comandi:
create table contatore (
val int
);
insert into contatore values (0);
e lo script conteggia.php che aggiunge un numero specificato dall'utente al valore corrente del contatore. Modificare lo script in modo che non si verifichino problemi nel caso di più esecuzioni concorrenti.
Soluzione
Ci sono due modi per risolvere il problema. Il primo è quello di racchiudere le due query SQL (la SELECT per recuperare il valore corrente del contatore e la UPDATE per modificarlo) tra i comando LOCK TABLES e UNLOCK TABLES. Si ottiene il file conteggia-lock1.php.
C'è tuttavia un'altra soluzione più semplice. Il problema che si verifica con la pagina conteggia.php è che, se ci sono due utenti in contemporanea, le select di entrambi gli utenti avvengono prima delle update. In realtà, se si vuole incrementare il valore del contatore, piuttosto che usare due query, una per leggere il valore corrente e uno per aggiornarlo, si può utilizzare una unica query update che fa il lavoro:
UPDATE contatore SET val=val+$incremento
Si ottiene allora il file conteggia-onlyupdate.php. Modificato in questo modo, anche senza blocchi di tabella, lo script non ha più alcun problema, in quanto la operazioni di UPDATE è una operazione "atomica" (deve essere svolta interamente, non può essere spezzata a metà).
ATTENZIONE. I comandi UPDATE, INSERT, DELETE e simili non sono vere operazioni atomiche, ma lo sono riga per riga. Ovvero, in una update multipla, l'aggiornamento di ogni singola riga è una opeazione atomica, ma tra l'aggiornamento di due righe è possibile che siano eseguite delle operazioni diverse provenienti da un altro thread.
Esercizio 2
Risolvere l'esercizio 1 usando gli advisory lock invece dei mandatory lock.
Soluzione
La soluzione è simile a quella dell'esercizio precedente, ma usando SELECT GET_LOCK()
e SELECT RELEASE_LOCK
invece dei comandi LOCK TABLES
e UNLOCK TABLES
. In più viene trattato il caso in cui la GET_LOCK
fallisce, presumibilmente per un congestionamento del sistema, visualizzando un opportuno messaggio di errore. Si ottiene il file conteggia-lock2.php.