Warning: count(): Parameter must be an array or an object that implements Countable in /home/pasokime/domains/mysql.lt/public_html/forumas/include/parser.php on line 820

Topic: Bandom daryti tranzakcija [MyISAM]

šitas dalykas pasirodo yra būtinesnis negu būtinas. Paskaitinėjau internete info, ir man kilo toks klausymas. Jeigu už užlokinu kokią nors lentelę (nuo 5.1 lyg ir bus galima tik vieną eilutę užlokint), ir su ta lentele dirbu ilgoje sesijoje, tuo tarpu kito vartotojo užklausai įvykdyti reikia tos pačios lentelės duomenų. Tai ar kito vartotojo užklausa mes kokią nor sklaidą kad šita lentelė užrakinta, ar tiesiog užklausa palauks, kol pirmoji užklausa atrakins lenteles?

Viskas lyg ir veikia (naudoju tą atveji, jeigu užklausa palauks kol bus atrakinta lentelė), bes nesugalvoju kaip patikrinti, nes ilgiausią užklausą kokią vykdžiau truko tik 0.06.

Be to, man neaišku dėl lock_type. Aš tai dėjau READ, nes manau jog su tokiu tipu šitos lentelės negalės kitos sesijos skaityti, o skriptas tikrai neleis nieko įrašynėti, kol duomenys yra nenuskaityti.

Be to, gal žinote kokios įdomios literatūros susijusios su mysql tranzakcija, nes skaitant mysql dokumentacija ne viskas aišku :)

Re: Bandom daryti tranzakcija [MyISAM]

visu pirma, tai myisam nepalaiko trasakciju. reik naudot innodb  ir innodb palaiko row lock`us :)
o del laukimo nezinau

Re: Bandom daryti tranzakcija [MyISAM]

tai mysql lentučiu užrakinti neįmanoma?

Re: Bandom daryti tranzakcija [MyISAM]

Lockai (užrakinimai) yra ... nevienareikšmis dalykas.

Yra lentelių lock'ai, yra eilučių lock'ai. Tranzaksija yra dar kitas dalykas.
(raktažodžiai: row level lock, table level lock, transaction).

Pradžiai reikia pakalbėti apie tai ką tu bandai padaryti ir kodėl, o tada tik rinktis tam tinkamus metodus ir įrankius. Gyventi be tranzaksijų ir lock'u galima, ir tai puikiai įrodo milijonai internetinių puslapių,.. bet, kad tie dalykai palengvina gyvenimą tai tikrai (-; Tik ar visada būtina jau abejoju..

Re: Bandom daryti tranzakcija [MyISAM]

Pas mane yra objektas, kuris sukuriamas pasiima duomenis iš vieno eilutės, o kai objektas sunaikinamas, visi duomenys yra užsaugomi toje eulutėje. Ir būna taip, jog vienas vartotojas gali užkrauti kito vartotojo objektą, ir nenoriu, jog du žmonės užkrautų tą patį obejektą ir abu užsaugoti skirtingus duomenis. Todėl man reikia, jog užkrovus viena objektą, visi kiti objektai kuriami su tuo pačiu ID palauktu tol, kol ankstensis objektas bus sunaikinamas (t.y. užsaugomas).

Re: Bandom daryti tranzakcija [MyISAM]

Tai surišk objekto_id su vartoto_id.

Re: Bandom daryti tranzakcija [MyISAM]

nelabai supratai.

Aš noriu, jog skriptas sukuręs obejktą vartotojas

<?
$user=new User(5);
?>

neleistų sukurti kitai užklausai vartotojo su ID=5, bet galėtų sukurti kitokio ID vartotojo, tol kol

1) nebus pirmoji sesija nutraukta
2) nebus vartotojo objektas sunaikinamas su unset($user)
3) objektas su ID=5 per 5 sekundes neatrakins kitoms sesijos šios eilutės

Aišku objekto sukūrimui naudojama tik viena eilutė, kurio ID sutampa su duomenų bazės lentelės ID. Objektas prieš sunaikinimą yra išsaugomas. Kitos sesijos kurios turi sukurti šitą objektą turi laukti savo eilės, kol bus atrakinta. Visiems sckriptam uždėtas 5 sekundžių timeoutas, tas klaidos  atveju turėtų šitos eilutės automatiškai atsirakinti (dėlto ir pamynėjau 3 punktą)

Re: Bandom daryti tranzakcija [MyISAM]

Aš manau, kad vartotojo ID turi būti sukuriamas maždaug taip:

INSERT INTO Users () VALUES ();
SELECT LAST_INSERT_ID();

.. kur Users lentoje yra PRIMAL_KEY su AUTO_INCREMENT.

Toliau visi duomenys ir būsenos jau rašomi turint tą ID. Tas gautas ID yra pririštas prie susijungimo su DB, todėl galima būti tikriem, kad gautas ID yra būtent tas, kurio mums reikia.

Trancakcijos reikalingos tada, kada vykdoma eilės operacijų (užklausų), tarp kurių įvykus tam tikriem įvykiams (pvz klaidos) turėtų būti atstatyta DB iki tos vietos, kai buvo vykdoma pirmoji užklausa.

Re: Bandom daryti tranzakcija [MyISAM]

Vistiek nesupratai.

Dažnai pas mane būna atveju, kai vienas vartotojas užkraunamas vienoje sesijoje, ir tas pats vartotojas užkraunams vieno sesijoje. Taigi sakykime pirmoje sesijoje tas vartotojas gauna labai daug pinigų, kurie yra užsaugomi, tačiau antroje sesijoje esantis vartotojo objektas susinaikindamas išsaugo senus duomenis ant viršaus, nes pinigų jisai negavo. Todėl šitas vartotojas lieka be pinigų.

10

Re: Bandom daryti tranzakcija [MyISAM]

tu cia kokia tais apskaitos programa darai ?

Re: Bandom daryti tranzakcija [MyISAM]

Nu dabar aiškiau. žodžiu tavo atveju trazakcija nelabai ką gali padėti.

Vienu atveju gali padėti row-lebel lock'as, kuris palaikomas InnoDB variklio, bet problema bus tame, kad vienai sesijai naujant duomenis iš tos eilutės viskas bus gerai, o kita sesija gaus error'ą, kad eilute "užrakinta", nes kažkas kitas jau redaguoja tuos duomenis... Todėl nežinau ar čia geras sprendimas.

Gal geriau tada kažkur (toje ar kitoje lentelėje) saugoti kažkokius tai papildomus duomenis, pvz.: sesijos_id ir laikas (kas paskutinis užsaugojo duomenis). Nuskaitant duomenis tuos papildomus laukus turėti prie objekto, o saugant tikrinti, ar kartais tame tarpe, kažkuri kita sesija nebuvo užrašius duomenų.

Kodėl netinka tranzakcija... todėl, kad yra dvi operacijos: skaitymo ir rašymo. Rašymo metu tu niekaip nežinai, ar duomenys buvo modifikuoti ar ne... net jeigu ir sužinotum, tai rollbackinus tranzakciją atstatytum tik... duomenų nuskaitymą, tai jokios čia naudos nematau.

Re: Bandom daryti tranzakcija [MyISAM]

Nu o jei nuskaitai duomenis ir juos kažkur nusikopini, o kai sunaikinėji objektą tai lygini tą seną kopiją su dabar esančiais duomenimis lentelėje. Jei jie skiriasi vadinas kažkas per tą laiką užrašė ant viršaus. Tokiu atveju atlieki atitinkamus veiksmus, kaip pvz pridedi pinigų skirtuma (atnaujinti pinigai (iš modifikuotos eilutės) - seni pinigai (iš kopijos) + atnaujinti pinigai (iš sunaikinamo objekto)) ar pan. :)

Re: Bandom daryti tranzakcija [MyISAM]

Tai nereikia visų duomenų (nes jų gali būti labai daug). Užtenka naudoti vieną stulpelį, pagal kurį galima būtų identifikuoti ar įrašas buvo modifikuotas ar ne.