Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP][Doctrine][MySQL] LOCK i UNLOCK, Strona zawieszona na kilka godzin...
Adi32
post
Post #1





Grupa: Zarejestrowani
Postów: 348
Pomógł: 26
Dołączył: 8.10.2008
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Witajcie.

(temat wisiał niespełna dobę w dziale Forum/Bazy danych/MySQL jednak postanowiłem go przenieść tutaj.
Mimo, że jest to mniej odpowiedni temat to w niewielkim stopniu pasuje a jest tutaj większy ruch).

Teoretycznie wszystkiego mógłbym się dowiedzieć chociażby z manuala, googla itp. ale postanowiłem napisać ponieważ przy aktualnym projekcie potrzebuje mieć pewność co do niektórych rzeczy.

Słowo wstępu.
Przeważnie korzystam z Doctrine ORM. Pojawiła się sytuacja, która zmusza mnie do skorzystania z blokowania tabel (przynajmniej tak mi się wydaje) a to co znalazłem w manualu Doctrina na temat blokowania nic mi nie pomogło, dlatego kod nieco się przeplata.

(1) - Zasada działania blokowania tabel...
Muszę w pewniej tabeli wykonać pewne akcie związane z usunięciem starych rekordów i dodaniem nowych. Ważne jest aby w trakcie wykonywania tych akcji nikt nie mógł nawet czytać z tej tabeli a gdyby jednak próbował to najlepiej jakby jego przeglądarka chwileczkę poczekała na zwolnienie blokady.

w tym celu zaprodukowałem taki kod:

  1. # Blokujemy tabele żeby nikt z niej nie czytał gdy będziemy ją przetwarzać
  2. Library_Baza::getInstance()->query("LOCK TABLES test_acl READ");
  3.  
  4. # kasujemy stare dane
  5. Doctrine_Query::create()->delete("TestAcl")->where("id_uzytkownik = $id")->execute();
  6.  
  7. //pre ($for_save);
  8.  
  9. # dodajemy nowe dane
  10. foreach ($for_save as $save) {
  11. $nowy = new TestAcl;
  12. $nowy->id_uzytkownik = $id;
  13. $nowy->fromArray($save);
  14. $nowy->save();
  15. }
  16.  
  17. # odblokowywujemy tabele
  18. Library_Baza::getInstance()->query("UNLOCK TABLES");


Czy jest on w porządku pod każdym względem? Czy spełnia przynajmniej to zadanie o które mi chodzi?

(2) - Dlaczego wykonanie powyższego kodu (testuje go od 3 dni) daje czasami taki efekt, że:
Dosłownie klikam "zapisz" co powoduje wykonanie się tego kodu i od tej pory przeglądarka czeka na odpowiedź z servera nawet kilka godzin? Można odświeżać, usuwać kod itp - nic nie pomaga. Czy dzieje się tak dlatego, że została zablokowana tabela (z której korzysta każda część skryptu) i cały czas czeka na jej odblokowanie?

(opcjonalnie) - Czy mogę ten efekt uzyskać bez przeplatania? Wykorzystując tylko Doctrine?


Miałem jeszcze jakieś pytania ale wyleciały mi z głowy...
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Używasz Doctrine w wersji 1.x, może już czas na przesiadkę na 2.2/2.3? O ile dobrze pamiętam nowa wersja wspiera blokowanie tabel - ale to tylko taka mała uwaga.
2. W rzeczy samej, może dojść do jakiegoś deadlocka.
3. Tutaj w zupełności wystarczy Ci najzwyklejsza transakcja, z poziomu PDO (nie trzeba się nawet bawić w zmianę poziomu izolacji). Co więcej nie ma potrzeby blokowania użytkownika (tabeli). Po prostu odczyta starą zawartość w momencie gdy nowa jest generowana - jest to przecież jedna z czterech podstawowych cech transakcji (ACID).
4. Czyli ostatecznie (w Doctrine będzie to wyglądało niemal identycznie)
  1. try {
  2. $pdo->beginTransaction();
  3.  
  4. $pdo->query('DELETE ... WHERE user_id = 5;');
  5. $stmt = $pdo->prepare('INSERT ... user_id = 5 ...;');
  6.  
  7. for (...) {
  8. $pdo->execute(array('param1' => 'value', 'param2' => 'value'));
  9. }
  10.  
  11. $pdo->commit();
  12. } catch (...) {
  13. $pdo->rollback();
  14. }
5. Jeżeli użytkownik (user_id#5) wykona zapytanie SELECT, w momencie gdy powyższy kod będzie dopiero na etapie pętli for, zwrócone zostaną wyniki sprzed ustanowienia transakcji, czyli sprzed usunięcia rekordów dot. tego użytkownika.

Ten post edytował Crozin 8.06.2012, 09:36:37
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 6.10.2025 - 01:48