Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [AJAX/php] dostęp do bazy - problem
Forum PHP.pl > Forum > PHP
patrykt
Witam.
Na raz wykonuję dwa wywołania pliku php przez AJAXa. W pliku php blokowany jest określony rekord (aby drugie wywołanie tego pliku się do niego nie dobrało), poddawany jest operacjom a następnie odblokowywany. Niestety, jakimś kosmicznym cudem obydwa pliki operują na tym rekordzie naraz :/

Jak się przed tym lepiej zabezpieczyć?
TomASS
A jak blokujesz rekord? Masz ustawioną jakąś flagę? Skąd wiesz, że nie są blokowane? Może po prostu rekord jest obrabiany najpierw przez jeden plik a później przez drugi.
patrykt
robię update tego rekordu ustawiając w kolumnie `blok` wartość 1, odblokowanie to analogicznie umieszczenie tam 0.
nospor
Moglbys pokazac caly kod php, jak blokujesz, jak operujesz.?
Pozatym skad wiesz, ze operuja w tym samym czasie?

ps: no i najwazniejsze: czy przed operowaniem sprawdzasz czy mozesz operowac? snitch.gif
patrykt
  1. <?
  2. //blokowanie:
  3.  $wyk = mysql_query("UPDATE feeds SET last_check_date="".time()."", blok=1 WHERE id=".$f['id']) or die(mysql_error());
  4. //odblokowanie:
  5. $wyk = mysql_query("UPDATE feeds SET blok=0 WHERE id=".$f['id']) or die(mysql_error());
  6. ?>


wiem, że wykonują się w tym samym czasie ponieważ wyniki wewnątrznej operacji są zdulbowane, pomimo tego, że drugi raz operacja może nastąpić dopiero kilka minut po zablokowaniu (ustawiany jest w innejkolumnie time()).

no i zanim w ogóle zacznie sięblkowanie jest sprawdzanie czy można smile.gif
nospor
Poprosze grzecznie jeszcze raz:
pokaz caly kod php, wlacznie z tym jak sprawdzasz czy zablokowane.
Bo to co tu pokazales, to nie ma w tym zadnego bledu, nic nie mowi konkretnego nam. Wiec jesli chcesz by ci ktos pomogl, to ty pomoz mu pomoc ci. Rozumiesz?
patrykt
  1. <?
  2.  
  3. $licz  = 0;
  4. $nowych = 0;
  5. $spr = 0;
  6.  
  7. $r1 = mysql_query("SELECT * FROM feeds WHERE user_id=".$user['id']." AND blok=0 ORDER BY name") or die(mysql_error());
  8. while($f = mysql_fetch_array($r1))
  9. {
  10. if($licz == 1) break;
  11. $cook[$f['cook_name1']] = $f['cook_wart1'];
  12. $cook[$f['cook_name2']] = $f['cook_wart2'];
  13.  
  14. if(mktime(date("H",$f['last_check_date']),date("i",$f['last_check_date']),1,date("m",$f['last_check_date']),date("d",$f['last_check_date'])) < mktime(date("H"),date("i")-$f['refresh'],1))
  15. {
  16. $spr++;
  17. $licz++;
  18. $wyk = mysql_query("UPDATE feeds SET last_check_date="".time()."", blok=1 WHERE id=".$f['id']) or die(mysql_error());
  19.  
  20. $rss = ($cook!='') ? fetch_rss($f['url'], $cook) : fetch_rss($f['url']);  
  21.  
  22. foreach($rss->items as $k=>$v)
  23. {  
  24. // WERYFIKACJA ////////////////////////////////////////
  25. // tutaj następują super tajne operacje
  26. ///////////////////////////////////////////////////////
  27. }
  28. $wyk = mysql_query("UPDATE feeds SET blok=0 WHERE id=".$f['id']) or die(mysql_error());
  29. }
  30.  
  31. $r9  = mysql_query("SELECT * FROM seen WHERE feed_id=".$f['id']." AND user_id=".$user['id']." AND seen=0 AND fav=0 AND safe=0") or die(mysql_error());
  32. $news = mysql_num_rows($r9);
  33.  
  34. $rss->channel['title'] = ($f['name']=='') ? stripslashes($f['namefeed']) : stripslashes($f['name']);
  35. if($nowych > 0 && $news > 0)
  36. $zmienna .= $f['id'].'#m.f#'.$rss->channel['title'].'#m.f#'.$news.'m###f';
  37.  
  38. }
  39.  
  40. echo ($spr==0) ? 'done' : krzaki($zmienna);
  41.  
  42. ?>
nospor
Od razu lepiej smile.gif

Jedyne co mi przychodzi do glowy, to ten warunek:
  1. <?php
  2. if(mktime(date("H",$f['last_check_date']),date("i",$f['last_check_date']),1,date("m",$f['last_check_date']),date("d",$f['last_check_date'])) < mktime(date("H"),date("i")-$f['refresh'],1))
  3. ?>

Skoro ci sie wykonuje jednak za czesto, to ten warunek musi byc nie spelniony. ALe jakos nie mam sily go analizowac.
Co chciales osiagnac? Ze przez iles tam sekund (minut) nie mozna modyfikowac tego rekordu? A nie mozna prosciej?
  1. <?php
  2. if ($f['last_check_date'] + $f['refresh'] * 60 < time()){
  3. //teraz updatuj
  4. }
  5. ?>
Dalem *60 bo chyba ty tam minuty trzymasz.

ps: przenosze bo z AJAXem to ma nie wiele wpolnego
patrykt
rzeczywiście, z tym ifem to jednak chyba przekombinowałem.
no ale nadal nie wiem co zrobić aby jednocześnie nie przechodził przez niego dwa wywołania pliku.
nospor
ale po zmianach w ifie nadal przechodzi?
Zrob proste debugowanie. Wyswietlaj (tudziesz wal do pliku) informacje jakie sa wartosci poszczegolnych danych, czy warunek napewno dobrze to wychwytuje, jakie ID i takie tam. W ten sposob powinienies do czegoś dojść. Bo w tym kodzie to nie widze zadnych wiekszych bledow, wiec trudno mi to sprawdzic.
Jedyne co mi sie rzucilo w oczy to to, ze raz piszesz w tabeli feeds: user_id, a raz piszesz id, ale zakladam ze oba pola są i sa sobie rownoznaczne w tej sytuacji.
patrykt
kiedyś zrobiłęm debugowanie i mnie szczerze mówiąc przeraziło - wszystko wykonało się nielogicznie NARAZ kilka razy.

ale mam inny pomysł - każde wywołanie funkcji będzie obejmowało inną przestrzeń rekordów smile.gif
Jim
Cytat(patrykt @ 13.09.2006, 11:54:44 ) *
kiedyś zrobiłęm debugowanie i mnie szczerze mówiąc przeraziło
offtopic
cicik
A nie prościej cały problem załatwić odpowiednim poziomem izolacji i transakcjami w samej bazie danych?
patrykt
Cytat(cicik @ 13.09.2006, 19:02:49 ) *
A nie prościej cały problem załatwić odpowiednim poziomem izolacji i transakcjami w samej bazie danych?

nie mam pojęcia o czym piszesz
php programmer
Czegoś tu nie kumam,
dałeś sobie specjalną kolumne o nazwie blok
z wartosciami 0 lub 1, ktore mówią czy można operować na rekordzie
a sprawdzasz jakimś dziwnym ifem z czasem,
to nie lepiej po prosu sprawdzić to pole "blok"?
cicik
Cytat(patrykt @ 14.09.2006, 10:08:36 ) *
nie mam pojęcia o czym piszesz


To trzeba poczytac. Google Twoim przyjacielem.
patrykt
Cytat(php programmer @ 14.09.2006, 08:24:31 ) *
Czegoś tu nie kumam,
dałeś sobie specjalną kolumne o nazwie blok
z wartosciami 0 lub 1, ktore mówią czy można operować na rekordzie
a sprawdzasz jakimś dziwnym ifem z czasem,
to nie lepiej po prosu sprawdzić to pole "blok"?

no właśnie na tym polegał problem, że te pliki były jednocześnie sprawdzane pomimo sprawdzania kolumny blok (kod wyżej)
Jim
obszerny artykuł na temat blokowania dostępu do rekordów > http://www.ddj.com/dept/database/192700218
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.