[Linux-Biella] [php] Variabili e liste dinamiche
Alberto Bertoli
alberto.bertoli a tiscali.it
Sab 7 Ago 2010 18:13:36 CEST
Il giorno gio, 05/08/2010 alle 21.01 +0200, Daniele Segato ha scritto:
[cut]
> no
> non funziona così
>
> ottimistico non significa "l'ultimo che arriva scrive"
>
> significa: "tutti lavorano facendo finta di essere i soli utenti del
> sistema"
>
> al momento di fare commit se ci sono modifiche concorrenti si beccano
> un'eccezione
>
Naturalmente hai ragione, avevo aggiunto apposta
"
PS : sò che non é esattamente così, é un'esempio approssimato.
"
In quanto mi premeva portare a Lorenzo, novello Apprendista Stregone,
una problematica che da utente stand-alone potrebbe aver trascurato.
E' che il codice php che aveva inoltrato precedentemente Lorenzo mi
dava l'idea di perdere le transazione con il DB. Per quanto mi consta il
web non é transazionale e per sopperire a questo problema sono nati gli
Application Server (Tomcat, JBoss, Bea Weblogic, Websphere ...), ma non
conosco php, quindi magari sbaglio.
Dal codice pareva che venisse generata una pagina web tramite una
select , che non crea alcun vincolo ed emessa una form via http al
client che in questo modo perde il "contatto" con il DBMS.
Successivamente, alla pressione del bottone "invia" della form, la
stessa, se del caso, procedesse ad un'instruzione di UPDATE, questa sì
avrebbe creato i vincoli pessimistico/ottimistico di cui sopra, ma utili
solo nel caso di UPDATE contemporaneo, mentre il ciclo SELECT/UPDATE é
molto più lungo.
Ad esempio
SELECT * FROM localita
Id ! Descrizione
------+------------------
1 ! Biella
2 ! Cossato
Client A ! Client B !
---------------------------+---------------------------+
SELECT * FROM localita ! !
!SELECT * FROM localita !
// Entrambi i client hanno la stessa tabella a video
// Il Client A modifica la descrizione della prima riga da "Biella"
// a "Torino"
UPDATE localita set ! !
Descrizione ="Torino" ! !
WHERE Id=1 ! !
*Il Client B a video ha ancora "Biella" nella prima riga*
Questa situazione, esternza al DB ha forti analogie con la "dirty
read", lettura sporca che i motori di DB tentano di evitare.
Anche se il driver utilizzato in php mantenesse il sincronismo della
transazione, cosa che non sò ma su cui nutro forti dubbi, Solo nel caso
di due UPDATE contemporanee entrano in gioco i vincoli del motore di
DB .
Se non mantiene in sincronismo, questa é fonte potenziale di problemi,
infatti il "Fine Manual" , che mi sono letto :-) dice :
1) USA il metodo pessimistico (in MySql forse si può impostare con SET
TRANSATION READ COMMITTMEND)
2) Fai la lettura con la SELECT normale e presenta i dati a video.
3) Memorizzati tutti i dati letti in variabili diverse da quelle del
video.
4) Per aggiornare, invece di utilizzare "UPDATE ..." , utilizzare SELECT
* FROM localita FOR UPDATE Descrizione WHERE ID=1" . La clausola FOR
UPDATE crea un vincolo pessimistico sul campo ed impedisce alle altre
transazioni di accedere in modifica al dato (dovrebbe restare in attesa
per un pò poi eventualmente dare timeout)
5) Confronta le variabili memorizzate prima con il record letto per
accertarti che nell'intervallo fra il punto 2 ed il 4, nessuno te le
abbia modificate. Se sono diverse *svincola* il record e poi torna al
punto 2, evidenziando il problema.
6) A questo punto con UPDATE puoi aggiornare i valori con la certezza
che tutto sia andato liscio.
Si deve avere l'accortezza di non lasciare possibili punti
d'interruzione fra il SELECT FOR UPDATE e l'UPDATE, ad esempio non si
deve emettere una finestra di richiesta all'utente perché il vincolo
blocca TUTTI sul sistema. Prima si svincola, poi si chiede all'utente
cosa vuol fare.
Chiaro che é molto più oneroso, però é a prova di bomba. Secondo mé é
rifarsi il metodo ottimistico, utilizzando il pessimistico su scala
esterna al DB ...
Qualunque contributo anche di altri é gradito, sopratutto su PHP e
MySql , che purtroppo conosco poco :-(
Ciaoooo.
Maggiori informazioni sulla lista
Linux