MySQL mindenkinek 9

, ,

A relációs adatbázisok előnyei közül ma a tranzakciókezelést szolgáljuk fel ebédre. Egy tranzakció tulajdonképpen egy nagy tányér SQL művelet amelyeknek csak együtt van értelme. Tipikus példa erre egy banki átutalás, amelynek során (jó esetben) az egyik számla egyenlegét akkor csökkentjük amikor a másikét növeljük.

Kicsit részletesebben egy banki átutalási művelet a következő lépésekből állna össze:

  • Állapítsuk meg, hogy a cél “B” számla létezik-e
  • Keressük ki az “A” (átutaló) számlát és állapítsuk meg az egyenlegét
  • Ha az egyenleg nagyobb mint az utalandó összeg akkor csökkentsük az egyenleget
  • “B” számla egyenlegéhez adjuk hozzá az összeget

Persze a valós életben ennél kb 25-ször több lépés zajlik le de a példánk szempontjából ez is elegendő.

Az átutalási művelet – azaz a tranzakció – csak akkor értelmezhető ha minden lépés végrehajtható egymás után. Egy ilyen műveletnél nem engedhető meg, hogy mondjuk az utolsó lépés nélkül végrehajtódjon az első három.

Az ilyen összecsomagolt műveletek együttes végrehajtására adnak lehetőséget a tranzakciók. Tranzakciók használatához egyenlőre a MySQL kizárólag az InnoDB táblatípust támogatja.

Az elv

A tranzakciók elve szerint a MySQL fogja szépen az összecsomagolt SQL műveleteket és elkezdi szépen sorban végrehajtani őket. Amennyiben minden rendben zajlik akkor véglegesíti a tranzakciót, és ebben a pillanatban kerülnek a tényleges módosítások az adattáblákba.

Amennyiben a tranzakció során bárhol hiba képződik, vagy mondjuk leáll a szerver akkor a tranzakció nem lesz végrehajtva, hanem a lépések visszavonásra kerülnek.

A gyakorlat

A gyakorlatban a fenti példa a következőképpen nézne ki egy php program keretében:

<?php

$utaltOsszeg = 500;

//célszámla kikeresése
$e = mysql_query("SELECT id FROM bankszamlak WHERE szamlaszam = '12345678-12345678'");
$celszamla = mysql_fetch_row($e);

//az indító számla egyenlege elegendő az utaláshoz?
$e = mysql_query("SELECT id, egyenleg FROM bankszamlak WHERE szamlaszam = '87654321-87654321'");
$utalo = mysql_fetch_array($e);

if($utalo['egyenleg'] >= $utaltOsszeg){
   //ha elegendő az egyenleg vonjuk le belőle
   //tranzakció indítása
   mysql_query("START TRANSACTION");
   mysql_query('UPDATE bankszamlak SET egyenleg = egyenleg-' . $utaltOsszeg . ' WHERE id = ' . $utalo['id']);

   //adjuk hozzá a célszámla egyenlegéhez
   mysql_query('UPDATE bankszamlak SET egyenleg = egyenleg+' . $utaltOsszeg . ' WHERE id = ' . $celszamla[0]);

   //eddig minden rendben hajtsuk végre a tranzakciót
   mysql_query('COMMIT');
}
?>

A fenti kód hatására ami egyből látszik az az, hogy ha nincs elegendő pénz akkor a tranzakció nem hajtódik végre. Persze eddig nem nyertünk semmit, ezt tisztán PHP-val is megtehettük volna tranzakciók nélkül. Ami ebből a kódból nem látszik, de történik mondjuk abban az esetben ha menet közben van egy áramkimaradás, megszakad a kommunikáció, vagy például megszűnik a fogadó számla pont ebben a pillanatban, az hogy COMMIT hiányában nem hajtódik végre a tranzakció. Ez azért van így mert a tranzakció alatt előforduló bármilyen hiba automatikusan meghívja a ROLLBACK eljárást.

Nem akarok jobban belebonyolódni a tranzakciók témájába, akit érdekel talál róla elegendő információt a neten, ízelítőként pedig ennyi is elég.

Jó kódolást!

Share
Mi az az RSS és mi az a PayPal?

Ez a bejegyzés rrd billentyűzetéből potyogott ki 2008 december 18. napján 12:00:44-kor. Eddig 2,402 olvasást ért meg. A visszajelzéseket nyomonkövetheted ezzel az RSS feed-el. Véleményt nyilváníthatsz, vagy trackbackolhatsz a saját oldaladon.

Ugrás fel

JólMegMondjad!

4 vélemény

  1. kirandulo
    2008 december 19. 14:19:25

    szuper a MySQL sorozat! respect, tanár úr! továbbra is várjuk a folytatást. (MySQL Workbench is kézre áll, köszönöm a választ az 1. részben.)

  2. crash
    2008 december 20. 16:43:13

    hella,
    Te a fizetős verziót használod? nekem sehogy sem sikerült összehozni hogy a linkelt mezőket kösse össze a vonal, és ne csak a tábla közepére mutasson

  3. rrd
    2008 december 20. 17:09:48

    Nem a linkelt mezőket köti össze hanem a táblákat. Ez normális. Némileg bonyolultabb lenne a vonalak megjelenítése ha a mezőket kötné össze. Képzeld el ha pl két tábla kapcsolatban van és az ábrán egymás alá teszed őket. Hogy mennének akkor a vonalak?

  4. kirandulo
    2008 december 23. 13:57:54

    MySQL Workbench 5.1.5 Alpha/GPL
    Igen, táblákat kapcsolunk össze, nem mezőket. Miután az eszköztáron kiválasztottuk a kapcsolat típusát, katt az egyik, majd a másik táblára. A szükséges idegen kulcsok (foreign key) automatikusan létrejönnek. (Helyesen mondom tanár úr?) A kapcsolat fölé húzva az egeret jelzésre kerül, hogy a kapcsolt táblák mely mezői között áll fent a kapcsolat.

Switch to our mobile site