Autor | Zpráva | ||
---|---|---|---|
slovakCZ Profil |
#1 · Zasláno: 10. 9. 2010, 10:13:20
Ahoj,
řeším problém s občasným dvojitým ukládáním do db. Mám takovýto skript, ktery zobrazuje kazdemu 10. navstevnikovi nejaky reklamni banner. Ted to testuju a kdyz drzim tlacitko F5, tak se mi naprosto nesmyslne ukladaji do databaze hodnoty do sloupce show. Vysvetleni nize, zde je ukazka: <?php /* vybere posledni zaznam z tabulky. ve sloupci SHOW je ulozeno bud 1 nebo 0. ID se navysuji automaticky o 1 */ $q = mysql_query("SELECT id, show FROM $dt ORDER BY id DESC LIMIT 1") or die(mysql_error()); while ($row = mysql_fetch_object($q)) { /* kdyz se show nerovna 1 tak pokracujeme, jelikoz nechceme reklamu zobrazi 2x hned po sobe. */ if($row->show!=1){ if($row->id%3==0){ echo 'jelikoz je to 3. navstevnik, tak mu zobrazime reklamu. Reklama se tedy zobrazuje kazde 3. navsteve'; $showen=1; } }else{ $showen=0; } /* do tabulky ulozime id a hodnotu 1 nebo 0 v zavislosti na tom, zda se navstevnikovi zobrazila reklama ci nikoliv */ $ins = mysql_query("INSERT INTO $dt VALUES('','$showen')") or die(mysql_error()); } ?> V pripade, ze mackam tlacitko F5 (refresh) v intervalu cca 0,3 sekundy, tak skript funguje v poradku. Databaze pak vypada nasledovne: sloupec ID - slupec SHOW 1 - 0 2 - 0 3 - 1 4 - 0 5 - 0 6 - 1 7 - 0 atd atd ovsem, kdyz tlacitko F5 drzim, tak se do databaze uklada neco takoveho: 1 - 0 2 - 0 3 - 1 4 - 1 5 - 0 6 - 1 7 - 0 8 - 1 9 - 1 10 - 0 11 -0 12 - 1 13 - 1 atd atd Vypada to, ze skript nedokaze v te "rychlosti" zjistit spravne ID.. nebo dotaz na aktualni radek pomoci selektu je proveden drive nez operace predchoziho ulozeni..... Jak je to ovsem mozne? Testuju u sebe na localhoste (mozna to je vykonem PC, je to mozne? mam stolni PC, WIN XP, Pentium D 3GHz, 3GHz, 2GB RAM). Jak necemu takovemu predejit? Problem nastane, kdyz skript nasadim na web, ktery je opravdu zatizen velkou navstevnosti. Na male strance to bude fungovat bez problemu. Dekuji za rady |
||
Joker Profil |
#2 · Zasláno: 10. 9. 2010, 11:13:47
slovakCZ:
„Vypada to, ze skript nedokaze v te "rychlosti" zjistit spravne ID“ To ne, prostě následující načtení skriptu udělá SELECT dříve, než to předchozí INSERT. Čili: - 3. běh skriptu udělá SELECT, poslední řádek je id=2, show=0. - 4. běh skriptu udělá SELECT a najde tentýž řádek. - 3. běh skriptu udělá INSERT a vloží řádek s id=3, show=1 - 4. běh skriptu udělá INSERT a vloží řádek s id=4, show=1 „Jak necemu takovemu predejit?“ - Minimalizovat dobu mezi dotazy, nebo to rovnou postavit jen na jednom dotazu. Zobrazení každému n-tému návštěvníkovi by šlo udělat jednoduše tak, že se udělá INSERT, přečte se hodnota jeho ID a zkontroluje, zda ID je dělitelné n. - Udělat nějaké řízení přístupu, jako zámek nebo token (před začátkem té vyhrazené operace si skript rezervuje token/zámek. Má-li token jiná instance, počká a zkusí to znovu. Až získá token, provede tu operaci a na jejím konci token uvolní). |
||
slovakCZ Profil |
#3 · Zasláno: 10. 9. 2010, 11:32:05
Joker:
Ok rozumím, děkuji ;-) |
||
TomášK Profil |
#4 · Zasláno: 10. 9. 2010, 13:27:39
Joker:
Transakce na úrovni databáze vynecháváš úmyslně? Zdají se mi přesně dělané pro tento případ, i jednodušší než vytváření zámků. Je v transakcích nějaký háček nebo jsi je jen neuvedl? |
||
Časová prodleva: 3 dny
|
|||
Vrtulnik Profil * |
#5 · Zasláno: 13. 9. 2010, 21:40:53
Transakce myslím umí jen InnoDB tabulky, pokud se nemylim.
|
||
Časová prodleva: 14 let
|
0