Topic: Tas pats sql query ta pacia sekunde
Sveiki! Ar galima kaip nors sql'ui uzdrausti ta pacia sekunde updatinti ta pati sql irasa lenteleje? Nes buna kad vartotojas narsydamas ir cronjob updatina ta pati irasa.
PHP ir MySQL programavimas, SQL užklausos, duomenų bazės, PHP scriptai, pagalba, diskusijos, pamokos ir straipsniai.
You are not logged in. Please login or register.
PHP ir MySQL → MySQL diegimas ir konfigūravimas → Tas pats sql query ta pacia sekunde
Sveiki! Ar galima kaip nors sql'ui uzdrausti ta pacia sekunde updatinti ta pati sql irasa lenteleje? Nes buna kad vartotojas narsydamas ir cronjob updatina ta pati irasa.
Gal gali patikslinti?
Pas tave ir vartotojas ir cron task'as modifikuoja tą patį įrašą?
Tau reikia arba trazakcijų arba table/row lock'ų, priklausomai nuo situacijos ir nuo aplinkybių.
Dar kartais gali tikti ir SELECT FOR UPDATE.
Daugiau info:
Tranzakcijos: http://dev.mysql.com/doc/refman/5.1/en/ … tions.html
Locking (lentų/įrašų rakinimas): http://dev.mysql.com/doc/refman/5.1/en/ … cking.html
SELECT FOR UPDATE: http://dev.mysql.com/doc/refman/5.1/en/ … reads.html
Gal gali patikslinti?
Pas tave ir vartotojas ir cron task'as modifikuoja tą patį įrašą?
Tau reikia arba trazakcijų arba table/row lock'ų, priklausomai nuo situacijos ir nuo aplinkybių.
Dar kartais gali tikti ir SELECT FOR UPDATE.
Daugiau info:
Tranzakcijos: http://dev.mysql.com/doc/refman/5.1/en/ … tions.html
Locking (lentų/įrašų rakinimas): http://dev.mysql.com/doc/refman/5.1/en/ … cking.html
SELECT FOR UPDATE: http://dev.mysql.com/doc/refman/5.1/en/ … reads.html
Taip,tarkim pinigai auga(per valanda tiek ir tiek),jie auginami per cronjob,kas sekunde(nes turi viskas labai tiksliai buti). Bet tarkim vartotojas nusprendzia tuos pinigus isleisti,jis kazka perka ir ivygdomas query(o tuo metu gali buti kad cronjob augina pinigus ir updatina ta pati irasa). Pasekmes tokios kad vartotojas kazka nusiperka ir nieko nepraranda. Na cia tik pvz.
Tiktu manau ir sitas:
mysql> LOCK TABLES real_table WRITE, temp_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM temp_table;
mysql> DELETE FROM temp_table;
mysql> UNLOCK TABLES;
tik ar jis nerakina visu lenteles irasu?
as noriu padaryti kad tie 2 query vienu metu ivykti negaletu,o butu taip: kuris query pirmas prasidejo,tas ivygdomas ir po jo iskart kitas.
Taip,tarkim pinigai auga(per valanda tiek ir tiek),jie auginami per cronjob,kas sekunde(nes turi viskas labai tiksliai buti). Bet tarkim vartotojas nusprendzia tuos pinigus isleisti,jis kazka perka ir ivygdomas query(o tuo metu gali buti kad cronjob augina pinigus ir updatina ta pati irasa). Pasekmes tokios kad vartotojas kazka nusiperka ir nieko nepraranda. Na cia tik pvz.
O kaip pas tave konkrečiai tas CRON'as prideda pinigu konkrečiam vartotojui, gal gali parodyt užklausas arba bent jau pseudo-užklausas. Nes mano manymu ten turėtų būti viena užklausa. Nes problemos gali kilti tik tada, kai yra daugiau negu viena užklausa, tarp kurių laike gali įsiterpti vartotojo sesijos užklausos.
Tiktu manau ir sitas:
mysql> LOCK TABLES real_table WRITE, temp_table WRITE; mysql> INSERT INTO real_table SELECT * FROM temp_table; mysql> DELETE FROM temp_table; mysql> UNLOCK TABLES;
tik ar jis nerakina visu lenteles irasu?
as noriu padaryti kad tie 2 query vienu metu ivykti negaletu,o butu taip: kuris query pirmas prasidejo,tas ivygdomas ir po jo iskart kitas.
Užtai ir daviau nuorodas, kad pasiskaityum. Kaip ir minėjau su rakinimais ir tranzakcijom yra tam tikrų aplinkybių. Pvz rakinti įrašus gali tik su InnoDB varikliu, su MyISAM gali rakinti tik visą lentą. Ir pan.
Exploder wrote:Taip,tarkim pinigai auga(per valanda tiek ir tiek),jie auginami per cronjob,kas sekunde(nes turi viskas labai tiksliai buti). Bet tarkim vartotojas nusprendzia tuos pinigus isleisti,jis kazka perka ir ivygdomas query(o tuo metu gali buti kad cronjob augina pinigus ir updatina ta pati irasa). Pasekmes tokios kad vartotojas kazka nusiperka ir nieko nepraranda. Na cia tik pvz.
O kaip pas tave konkrečiai tas CRON'as prideda pinigu konkrečiam vartotojui, gal gali parodyt užklausas arba bent jau pseudo-užklausas. Nes mano manymu ten turėtų būti viena užklausa. Nes problemos gali kilti tik tada, kai yra daugiau negu viena užklausa, tarp kurių laike gali įsiterpti vartotojo sesijos užklausos.
Ten be ciklo as niekaip neapsiesiu,nes nuskaites vienus duomenis is ju dar reikia ir daugiau isgauti ir pan.
tarkim paima updatint irasa su pinigai=100. (ir useris ir cron ta pacia sekunde):
useris updatina(perka uz 10 pinigu),lieka 90 ir tada tuo paciu cron updatina priaugina 1 piniga,bet keliom milisekundem veliau,tai gaunasi kad lieka pinigu 101,nors turetu buti 91. Nes cronjob kai nuskaite buvo 100. Na nezinau ar aiskiai as cia paaiskinau.
Exploder wrote:Tiktu manau ir sitas:
mysql> LOCK TABLES real_table WRITE, temp_table WRITE; mysql> INSERT INTO real_table SELECT * FROM temp_table; mysql> DELETE FROM temp_table; mysql> UNLOCK TABLES;
tik ar jis nerakina visu lenteles irasu?
as noriu padaryti kad tie 2 query vienu metu ivykti negaletu,o butu taip: kuris query pirmas prasidejo,tas ivygdomas ir po jo iskart kitas.Užtai ir daviau nuorodas, kad pasiskaityum. Kaip ir minėjau su rakinimais ir tranzakcijom yra tam tikrų aplinkybių. Pvz rakinti įrašus gali tik su InnoDB varikliu, su MyISAM gali rakinti tik visą lentą. Ir pan.
As angliskai nesuprantu,tame ir beda didziausia. Kaip atrodytu VIENO vartotojo duomenu lenteleje uzrakinimas? Gal pvz gali numest?
As angliskai nesuprantu,tame ir beda didziausia. Kaip atrodytu VIENO vartotojo duomenu lenteleje uzrakinimas? Gal pvz gali numest?
Kaip aš tau pateiksiu pavyzdį, jeigu tu net neparašai kokį variklį naudoji ir neskaitai, ką jau parašiau? (-;
Beje, pirmiausia gal ir reikėtų pasimokyti anglų kalbos, nes be jos toli nenueisi... visa dokumentacija, pavyzdžiai, knygos yra angliškai.
Aš juk negaliu dirbti vertėju...: http://dev.mysql.com/doc/refman/5.0/en/ … modes.html
Ten be ciklo as niekaip neapsiesiu,nes nuskaites vienus duomenis is ju dar reikia ir daugiau isgauti ir pan.
Na aš kalbėjau, kad ten net dviejų užklausų neturi būti, o tu jau apie ciklą dar kalbėt pradedi (-;
tarkim paima updatint irasa su pinigai=100. (ir useris ir cron ta pacia sekunde):
useris updatina(perka uz 10 pinigu),lieka 90 ir tada tuo paciu cron updatina priaugina 1 piniga,bet keliom milisekundem veliau,tai gaunasi kad lieka pinigu 101,nors turetu buti 91. Nes cronjob kai nuskaite buvo 100.
Nu tai kame problema? Juk yra dvi užklausos einančios viena paskui kitą: nesvarbu kokia eile:
a) pirma CRON'as prideda pinigų, antra vartotojas kažką perka;
b) pirma vartotojas kažką perka, antra CRON'as prideda pinigų;
Nesvarbu ar tarp tų užklausų valanda ar milisekundė - konflikto čia nėra.
Turi parodyk konkrečiau savo užklausas/ciklus (-;
O nesvarstei kiek kitokio varianto. Kiekvienas įvykis yra (tiek pinigų daugėjimas, tiek mažėjimas) išsaugomas kaip atskira eilutė. Visą senesnį nei X laiko balansą flatinant (nežianu kaip kitaip išsireikšti). Arba excelyje panašiai veikia SubTotal skaičiavimas
pvz:
lentele PINIGAI
id | user_id | suma | timestamp
1 | 12 | 700 | 12:10 <- balansas iš anksčiau
5 | 12 | 3 | 12:11 <- įkrito pinigų
6 | 12 | 5 | 12:12 <- dar įkrito pinigų
9 | 12 | -23 | 12:11 <- perkam ginklą
.......
esamą balansą gaunam su (pirkimas bus neigimas ,todėl suma mažės)
SELECT SUM(suma) FROM `pinigai` WHERE user_id = 12
Tačiau taip saugant prisikauptų daug nereikalingų įrašų. Todėl su cornu kas X laiko apsivalom nuo senų
$laikas = time() - X; <laiką siačiaujam PHP, nes mysql jo reikės du kartus, o jei tarp užklausų bus bent sekundė tarpas, bus labai negerai :)
INSERT INTO pinigai
SELECT null, user_id, SUM(suma), NOW() FROM `pinigai` WHERE user_id = 12 AND timestamp < $laikas
t.y įrašom balansą kaip naują įrašą. Tada tirnam senus
DELET FROM pinigai WHERE user_id = 12 AND timestamp < $laikas
Lukas: kol kas nepainiok žmogaus papildomai (-; Jis ir taip susipainiojęs.
Na turint visų įvykių logus galima paišyti baisiai gražią statistiką pas daugiausiai apyvartos padarė, kas kokią strategiją naudoja. O gal mokesčių nemoka (čytina etc) :) Aš visada bandau žvelgti į ateitį ;)
Na turint visų įvykių logus galima paišyti baisiai gražią statistiką pas daugiausiai apyvartos padarė, kas kokią strategiją naudoja. O gal mokesčių nemoka (čytina etc) :) Aš visada bandau žvelgti į ateitį ;)
Operacijų log'as ir turi likti logu, kurį tu dažniausiai analizuosi ne online.
Kažkokių tai ataskaitų duomenys ir turi būti paruošiami taip, kad juos būtų galima tiesiog nuskaityti, neatlikinėjant kas kartą log'o analizės.
O autoriaus problema visai kitur. Jis kol kas bando pasakyti, kad jam du UPDATE kažkaip sugeba įvykti vienu metu ir vienas kitam trukdyti. Nors akivaizdu, kad tikriausiai pas jį bėdos kažkur kitur, nes kaip ten bebūtų UPDATE vyksta vienas po kito.
Lukas wrote:Na turint visų įvykių logus galima paišyti baisiai gražią statistiką pas daugiausiai apyvartos padarė, kas kokią strategiją naudoja. O gal mokesčių nemoka (čytina etc) :) Aš visada bandau žvelgti į ateitį ;)
Operacijų log'as ir turi likti logu, kurį tu dažniausiai analizuosi ne online.
Kažkokių tai ataskaitų duomenys ir turi būti paruošiami taip, kad juos būtų galima tiesiog nuskaityti, neatlikinėjant kas kartą log'o analizės.
O autoriaus problema visai kitur. Jis kol kas bando pasakyti, kad jam du UPDATE kažkaip sugeba įvykti vienu metu ir vienas kitam trukdyti. Nors akivaizdu, kad tikriausiai pas jį bėdos kažkur kitur, nes kaip ten bebūtų UPDATE vyksta vienas po kito.
Jau issitaisiau.
didžiausia bėda gaunasi kai taip naudojamas cron'as, tereikia paskaičiuoti laiko intervalą nuo paskutinio updeito,
offline user;iai nesiskaito, o cron'as visvien juos updeitina - nesąmonė.
PHP ir MySQL → MySQL diegimas ir konfigūravimas → Tas pats sql query ta pacia sekunde
Powered by PunBB, supported by Informer Technologies, Inc.