Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wiele zapytań równocześnie
Forum PHP.pl > Forum > Bazy danych > PostgreSQL
ayeo
Witam wszystkich czytających....

Opisze może na przykładzie o co mi chodzi:
Skrypt tworzy 10 osobowe grupy. Kazdy uzytkownik moze sie zapisac do grupy. Skrypt zapisuje uzytkownika do pierwszej wolnej grupy, jesli nie ma wolnej to zaklada kolejna grupe i powtarza poprzedni krok. Proste.

Problem polega na tym, ze jak to sie wszystko zachowa gdy wielu uzytkownikow sprobuje zapisac sie jednoczesnie?
W sensie skrypt sprawdzi, ze w grupie jest 9 osob (2 razy niezaleznie) i dopisze dwie osoby i bedzie 11...
SongoQ
Prawdopodobienstwo czegos takiego jest male. Ale w pg mozesz zrobic tak dodatkowa tabela. Najpierw lock na tabele potem sprawdzenie utworzenie grupy itd a potem zdjecie. To wszystko mozesz zamknac w funkcji.
ayeo
Dziekuje za szybka odpowiedz. Problem w tym, ze musze miec 100%pewnosci, ze grupa bedzie zawierala po 10 userow... Nie wiem czy dobrze rozumiem transakcje bo co jesli:
- dla usera sprawdzam (w izolacji) ilosc uzytkownikow w grupie
- jesli jest mniej niz 10 userow w grupie dopisuje do grupy usera A
- koncze transakcje

Problem:
- user B (w tym samym czasie probuje sie dopisac)
- sprawdzanie ilosci osob w grupie nie uwzglednia uzytkownika A bo transakcja jest nie zakonczona i stwierdza, ze jest mniej niz 10 osob w grupie
- zapisanie usera B do grupy
- koniec transakcji sad.gif

Konczac transakcje dla usera B dopisze go jako 11 do grupy bo sprawdzanie ilosci userow w grupie dalo bledny wynik...

Czy jest mozliwe w PG jakies kolejkowanie w sensie blokowanie kolejnych zapytan na czas trwania poprzednich? Chcialbym, zeby skrypt poprostu poczekal na wolny dostep do bazy, a nie zeby odzucal zapytanie.



EDIT
Tak sobie mysle (jak sie mysle to prosze mnie wyprowadzic z bledu) ze jesli stopien izolacji dam na read uncommited to bedzie ok. Transakcje niezalezne beda widzialy zmiany przed ich zaakceptowaniem. Userzy nie musza byc dopisywani po kolei do grup, a funkcja szuka pierwszej wolnej grupy wiec jak transakcje odrzuce to pozniej i tak kogos sie dodat do starej grupy smile.gif


EDIT2
No panowie!! Smialo pisac swoje sugestie smile.gif
fulgore
miałem kiedys podobny problem ale z ankietami - do aplikacji mialo sie logowac wielu uzytkownikow i pobierac ankiety w celu obdzwonienia uzytkownikow z ankiety i przeprowadzenia rozmowy.

rozwiazalem go w najprostszy sposob jaki wydawal mi sie sluszny, a mianowicie:

mialem tabele ankiety i pobrane_ankiety. Funkcja najpierw sprawdzala czy dana ankieta jest pobrana (zapisana w pobrane_ankiety) i jak nie byla to ja pobierała, ale - I TU JEST ROZWIAZANIE:) - w przypadku gdyby w trakcie zapisu tej ankiety do tabeli pobrane_ankiety inny użytkownik już zapisal ja szybciej postanowilem zrobic w krotkim odstepie czasu kolejne zapytanie sprawdzające czy rekordy w tabeli pobrane_ankiety sie niepowtarzaja jesli by sie powtarzaly kasowana byla by ta ankieta i proces prebiegal by od nowa. (w tabeli pobrane_ankiety bylo pole id auto_increment wiec osoba kutara w takim wypadku miala niższe id obslugiwala ankiete a ta reszta losowala ponownie)

Takie rozwiazanie dla moich potrzeb wystarczalo a mialo znaczenie bo aplikacja byla wykozystywana przez powana firme i niemogli sobie pozwolic na dzwonienie dwa razy do tej samej osoby - wizerunek firmy by podupadł smile.gif


pozdrawiam
prond
Panowie, po co te tricki ? Wystarczy zrobic to wlasnie tak, jak napisal SongoQ.
Jak chcesz byc na 100% pewien izolacji transakcji uzyj locka 'ACCESS EXCLUSIVE' przy modyfikacji grup:
  1. BEGIN WORK;
  2. LOCK TABLE groups IN ACCESS EXCLUSIVE;
  3. -- SELECT costam
  4. -- INSERT / UPDATE etc.
  5. COMMIT WORK;
ayeo
Może mi ktoś wytłumaczyć co się stanie jeśli zrobię locka ('ACCESS EXCLUSIVE'), a kolejny skrypt będzie się łączył dla innego usera? W sensie poczeka, aż lock zostanie zdjęty czy co?
msulik
Si. Czyż nie mówi o tym manual postgresa?
Cytat
LOCK TABLE obtains a table-level lock, waiting if necessary for any conflicting locks to be released.
ayeo
A można blokować pojedyncze rekordy (ROWS) ?

EDIT: Podobno postgres zakłada row-level lock automatycznie dla transakcji modyfikujących dany wiersz? W sensie nie ma się co przejmować? smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.