![]() |
![]() ![]() |
![]() |
![]()
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:
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... -------------------- Wolałem języki z rodziny C ale poszedłem na łatwizne...
|
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 207 Pomógł: 18 Dołączył: 4.09.2010 Skąd: warszawa Ostrzeżenie: (0%) ![]() ![]() |
Pojawiła się sytuacja, która zmusza mnie do skorzystania z blokowania tabel (przynajmniej tak mi się wydaje) moim zdaniem źle kombinujesz. istnieje bardzo niewielka szansa, że faktycznie blokowanie tabeli jest w twoim przypadku prawidłowym rozwiązaniem problemu. ponieważ nie napisałeś nic więcej PO CO robisz blokowanie, skupiając się na JAK to zrobić, to proponuję abyś naświetlił szerzej kontekst. a jako zadanie domowe;), pogooglaj w tematach: - transakcje - blokowanie tabeli a wydajność - silniki mysql, różnice/zalety - granularity locking |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 348 Pomógł: 26 Dołączył: 8.10.2008 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
Dziękuję za odpowiedź, już traciłem nadzieję.
Na transakcjach się znam, przynajmniej tak mi się wydaje... W moim przypadku sprawę wydajności można pominąć, chodzi o jedną małą blokadę w pewniej okoliczności. Korzystam z silnika InnoDB ze względu na relacyjność. W połączeniu z Doctrinem i warstwą aplikacji "Model" zapytania łączone to sama przyjemność. Wiem, że z pewnych względów zapytania natywne są lepsze jeżeli chodzi o wydajność ale przy niewielkich projektach różnica jest znikoma, tymbardziej jeżeli stosuje się system cachowania, który mam zamiar wprowadzić. Trochę zszedłem z tematu także opiszę najpierw o co mi tak na prawdę chodzi. Postanowiłem zrobić jakiś nowy system ACL w pełni zarządzalny który uwzględniałby wszystkie lokacje i akcje z nimi związane. Administrator posiada drzewo (mapę strony) dla określonego użytkownika. Modul --Controller ----Akcja ------Parametr (opcjonalnie) I system checkboxów do zaznaczanie czy użytkownik ma posiadać dostęp czy nie. tabela w bazie jest prosta, zawiera kolumny: id_uzytkownik, module, controller, action, param Administrator ma dostęp wszędzie więc wpis wygląda tak: 1,*,*,*,* Użytkownik który ma wszelkie prawa odnoście strony i może jedynie zajrzeć do panelu administracyjnewgo będzie psoiadał 2 wpisy: 2,index,*,*,* 2,admin,*,-,- I to już działa ale chciałbym aby tabela była zablokowana w momencie gdy admin zmienia uprawnienia, ponieważ zmiana uprawnień polega na skasowaniu wszystkich wpisów dla danego użytkownika i dodania nowych. Próbowałem różnych akcji względem tabeli test_acl i rezultat jest taki, że teraz mogę jedynie z niej czytać. Nie mogę w niej nic zmienią ani usunąć nawet z poziomu phpmyadmina. Jak spróbuje to strona się zawiesza - ładuje się, czeka na odpowiedź z serwera aż usune ciasteczka sesji. Pozdrawiam. -------------------- Wolałem języki z rodziny C ale poszedłem na łatwizne...
|
|
|
![]()
Post
#4
|
|
![]() 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) 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 |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 348 Pomógł: 26 Dołączył: 8.10.2008 Skąd: Lublin 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. Korzystałem z Doctrina2 przelotnie (specialnie zaktualizowałem wersję php do nowszej) jednak wykonywanie zapytań było mniej wygodne - spodobała mi sie formuła z Doctrine1. Być może za słabo zapoznałem się z D2? 2. W rzeczy samej, może dojść do jakiegoś deadlocka. A jak teraz z niego wyjść? W manualu SQL znalazłem różne polecenia i zapytania jednak mam Access Denited przy próbie ich wykonania. Uważam że skoro bez konta roota zrobiłem deadlocka to i powinienem móc go cofnąć... 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). No faktycznie, masz rację - nie pomyślałem o tym. 4. Czyli ostatecznie (w Doctrine będzie to wyglądało niemal identycznie) 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. Dzięki Crozin. -------------------- Wolałem języki z rodziny C ale poszedłem na łatwizne...
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 15.07.2025 - 18:00 |