PHP / MySQL Simultaneitatea - Scrie în funcție de citire - secțiunea critică

voturi
3

Am un site web PHP + MySQL rulează. Este un sistem multiutilizator și de cele mai multe tabele MySQL sunt bazate pe MyISAM.

Situația următoare ma nedumerit în ultimele câteva ore: Am doi utilizatori (simultani) A, B. Ambele vor face acest lucru:

  1. Efectuați o citire de operare pe tabelul 1
  2. Efectuați o operație de scriere pe un alt Tabelul 2 (numai în cazul în care operația anterioară Read va returna un rezultat distinct, de exemplu STATUS = „OK“)

B este un pic întârziat față de A.

Deci, va avea loc așa:

  • Utilizatorul A efectuează o citire pe tabelul 1 și vede STATUS = „OK“.
  • (User A programărilor scrie pe tabelul 2)
  • Utilizatorul B efectuează o citire pe tabelul 1 și vede încă STATUS = „OK“.
  • Utilizatorul A (mai rezultând STATUS = „NOT OK“) efectuează Scrie pe tabelul 2
  • Utilizatorul B efectuează scrie pe tabelul 2 (presupunând STATUS = OK)

Cred că am putea preveni acest lucru, dacă Reading tabelul 1 și Scrierea în tabelul 2 au fost definite ca o secțiune critică și va fi executată atomically. Știu că acest lucru funcționează perfect bine în Java cu fire etc., cu toate acestea, în PHP nu există nici o comunicare fir, în măsura în care știu.

Deci, soluția la problema mea trebuie să fie legate de baze de date, nu? Vreo idee?

Mulțumesc mult!

Întrebat 19/08/2012 la 15:05
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
3

Calea dreapta: Utilizați InnoDB și tranzacții .

The Works wrong-but-Way: Utilizați GET_LOCK () funcția MySQL pentru a obține o blocare exclusivă numit înainte de efectuarea operațiunilor de baze de date. Când sunteți Don, eliberați de blocare , cu RELEASE_LOCK () . Deoarece doar un singur client poate deține o anumită blocare, acest lucru se va asigura că nu există niciodată mai mult de o instanță a script - ul în secțiunea „critică“, în același timp.

Pseudo cod:

SELECT GET_LOCK('mylock', 10);
If the query returned "1":
    //Read from Table 1
    //Update Table 2
    SELECT RELEASE_LOCK('mylock');
Else:
    //Another instance has been holding the lock for > 10 seconds...
Publicat 19/08/2012 la 15:26
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more