ugrás a tartalomhoz

MySql tranzakció.

s_volenszki · 2007. Már. 14. (Sze), 21.02
Sziasztok!

A prog.hu-n olvastam egy érdekes topicot mysql lock table és mysql lock row témában, és ott láttam a következő kifejezést:

...indítok egy tranzakciót...

Tudna valaki egy MySql tranzakció alapok (akár angolul) tutorialt?

Köszike: s_volenszki

ps.:
Guglit csavargattam, de nem találtam konkrét példát, és én audio-vizuális típus vagyok! :)
 
1

link a mysql tranzakcio+innoDB-hez

toro · 2007. Már. 14. (Sze), 23.23
http://dev.mysql.com/books/mysqlpress/mysql-tutorial/ch10.html
2

tutorial

s_volenszki · 2007. Már. 15. (Cs), 09.01
Köszönöm szépen!

s_volenszki
3

Találtam már több topikot,

mahoo · 2010. Aug. 26. (Cs), 15.28
Találtam már több topikot, ezért sem nyitottam újat, de talán az én problémám még nem merült fel.

Szóval van egy 'nested-tree' típusú adatmodellem, melyben tagokat lehet regisztrálni szépen egymás alá. Amíg csak egy regisztrátor van, addig minden rendben van.
Ha azonban egy időben már többen szeretnének regelni, akkor részben a 'nested-tree' logikája miatt, részben pedig, hogy a regisztráció több sql parancsból áll, szeretném az érintett táblákat lockolni és a regisztráció folyamatát tranzakcióba foglalni.

Sajnos már a lock-oláson elvéreztem :(.

Sql parancs a következő volt:
LOCK TABLE felhasznalo_struktura READ melyet kiadtam, a struktura_1.php fájlban.

Egyik böngészőben betöltöttem azt az oldalt, mely a struktura_1.php tölti be, és nem tudott létrejönni a fastruktúra. Eddig jó!
Egy másik böngészőben pedig betöltöttem egy olyan oldalt ami a struktura_2.php-t húzza be, amely szintén ua-t a lockolt táblát használja. Ennek ellenére létre tudott jönni a fastruktúra. Ez már nem jó!

Kérdésem, hogy ez normális e? Ha igen, akkor miért, és hogy valósítható meg az amit szeretnék, azaz egy LOCK TABLE kiadása után egyik php kód se férhessen hozzá az adott táblához?
Ja, és UNLOCK nélkül, a LOCK parancs eltávolítása a programkódból mellett ismét újra olvashatóvá vált a tábla. Nem értem... nem kellene előbb unlockolni???

Szóval semmit nem értek :( egy kis segítség jó lenne!

Köszönöm!
4

Kapcsolat

Poetro · 2010. Aug. 26. (Cs), 17.08
Mivel a kapcsolat a MySQL-hez befejeződött mire megnyitottad a struktura_2.php ezért a tábla már addigra valószínűleg unlock-olódott, mivel az a folyamat, ami lockolta már megszűnt. Egyébként a tranzakció nem erről szól, hogy te kézzel lockolod a táblát, hanem elkezded a tranzakciót, megadod a lépéseit és futtatod. A MySQL pedig helyetted egy atomi lépésként hajtja végre, azaz lezárja és megnyitja a kívánt táblákat. Lásd: START TRANSACTION, COMMIT, and ROLLBACK Syntax
5

Asszem értem mit mondasz, de

mahoo · 2010. Aug. 26. (Cs), 18.59
Asszem értem mit mondasz, de felmerül bennem a kérdés, hogy akkor a lock mire is való valójában és hogyan kell használni. Én abban a hitben voltam, hogy ezzel zárolhatok egy táblát php kódból és addig nem férhetnek hozzá, mem lehet rajta lekérdezés végrehajtani, amíg fel nem oldom azt.

De akkor megkérdem másképp is: ha tranzakciót indítok, akkor az összes érintett tábla automatikusan zárólódik amig a trancakció végig nem fut?
6

Amíg fut

Poetro · 2010. Aug. 26. (Cs), 19.14
Én abban a hitben voltam, hogy ezzel zárolhatok egy táblát php kódból és addig nem férhetnek hozzá, mem lehet rajta lekérdezés végrehajtani, amíg fel nem oldom azt.

Amíg a PHP kódod fut, addig semelyik másik lekérdezést nem lehet rajta végrehajtani. Tegyük fel, hogy a PHP kódod elején lezárod a táblát. Majd a PHP kódod fut 10 másodpercig. Ezalatt az idő alatt nem lehet lekérdezést intézni a táblához. Tehát ha ezzel párhuzamosan futna mondjuk még egy PHP szkript (tehát az alatt a 10 másodperc alatt amíg a másik szkript lefoglalta a táblát), akkor addig az vagy várakozik vagy pedig figyelmeztetéssel elszáll.
De akkor megkérdem másképp is: ha tranzakciót indítok, akkor az összes érintett tábla automatikusan zárólódik amig a trancakció végig nem fut?

Ez részben igaz. Van olyan ami olvasásra, van, ami írásra zárolódik, ezt az adatbázismotor a lekérdezések alapján eldönti. De érdemesebb erről elolvasni a dokumentációt.
7

Most már okosabb lettem,

mahoo · 2010. Aug. 26. (Cs), 20.44
Most már okosabb lettem, köszönöm Poetro! Akkor utánaolvasok ennek még...
8

Sajnos nem boldogulok :( Ez

mahoo · 2010. Szep. 6. (H), 13.33
Sajnos nem boldogulok :( Ez bizonyosan a hiányos tudásomnak köszönhető, de hiába keresgélek a neten, nem megy...

Van két php fájl, ebből az egyik a tranz.php:

mysql_query("SET AUTOCOMMIT=0");
mysql_query("begin");
mysql_query("select tartalom from hirek limit 3 order by idhirek")
while(mysql_query_fetch()) {
$temp[] = $row->tartalom;
}

for($c=0;$c<3;$c++){
mysql_query("UPDATE hirek set tartalom = '$temp[$c]' WHERE idhirek = $c");
sleep(5);
}

mysql_query("end");



És a másik, list.php:


mysql_query("select tartalom from hirek limit 3")
while(mysql_query_fetch()) {
echo = $row->tartalom;
}



Elindítom a tranz.php-t, melynek a futási ideje kb. 15s de ezalatt, ha egy másik böngészőben meghivom a list.php, akkor az gond nélkül lefut.
Pedig én az szeretném, hogy ne férjen addig hozzá senki az adott táblához, amíg egy update fut rajta. Ez tök alap dolog lenne, mégsem tudom megcsinálni.

Az is érdekelne még, hogy ha egy tranzakción belül több update van több különböző táblán, akkor a 'begin' után az összes tábla zárolódik vagy csak az ahol éppen a tranzakció tart. Én azt szeretném hogy az összes zárolódjon, mind írásra, mind olvasásra.

Ha egy kis példával valaki tudna segítani az nagyon jó lenne. Köszönöm!
9

Tranzakció fut

Poetro · 2010. Szep. 6. (H), 14.08
A tranzakció még nem fut, csak akkor amikor elküldöd futni. Azaz amikor elindítod a COMMIT-ot akkor indul a tranzakció. Azaz amit előtte csinálsz azzal csak a tranzakciót készíted elő. És persze PHP műveleteket se csinálj a tranzakcióban, elvégre pont az a lényege a tranzakciónak, hogy az elejétől a végéig a MySQL-é a vezérlés. Van rengeteg példa az előbb említett linken is. Például:
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;
Itt a START és a COMMIT rész közötti futás között nem tudnak más folyamatok a táblákhoz férni.

Amit te írtál ott a tranzakció az end utasítás kiadásakor indul, addig csak előkészítetted a tranzakciót, és még jót is aludtál közben. Amennyiben sleep-elgetni akarsz, akkor használj LOCK-ot.
10

Nagyon jó!

mahoo · 2010. Szep. 6. (H), 14.25
Köszönöm Poetro, úgy látszik én nagyon rosszul álltam neki, 1000 köszönet!!!

És csak akkor, hogy tényleg jól értem: ha updete-elem a hirek és például még a cikkek táblást a START és COMMIT között akkor a start után, MINDKÉT TÁBLA EGYIDŐBEN válik elérhetetlenné futás közben mind irásra és olvasásra egyaránt más folyamatok számára? Azaz 'nem kell megvárni' amíg az első update végrehajt 100.000 módosítást a hírek tblán és csak azután 'zárolja' a cikkek táblát?