ugrás a tartalomhoz

Mi van, ha elszáll a MySQL tranzakció közben

Max Logan · 2007. Jún. 18. (H), 10.19
A rendszer amit fejlesztek több ponton használ tranzakció kezelést.

A kérdésem az lenne, hogy mekkora az esélye annak, hogy éppen a tranzakció kellős közepén száll el (lesz elérhetetlen) a MySQL szerver?

Ilyenkor mi történik a tranzakcióval, lévén, hogy sem a COMMIT, sem a ROLLBACK parancs nem kerül kiadásra?
 
1

szerintem...

s_volenszki · 2007. Jún. 18. (H), 13.10
Szia!

php + mysql tapasztalatok alapján:

A mysql tranzakció kezeléssel én is csak nem rég ismerkedtem meg, és az én véleményem a következő:

Nekem ez úgy működik, hogy van egy $globalResult változóm ami alapértelmezetten true. Elindítom a tranzakciót, és minden adatbázis műveletet figyelek hogy az eredménye true-e. Ha nem, $globalResult = false; meg még egy hibakódot is adok neki (egy másik változónak), hogy tudjam, a folyamatok közül hol akadtam fenn.

Ha minden lefutott ellenőrzésre kerül a $globalResult változó, és ha true akkor commit.

Na már most a te teóriád szerint megszakad a kapcsolat az adatbázis szerverrel, ezért valamelyik művelet eredménye képen a $globalResult false lesz, aminek a következménye a végén a rollback.

Ebben az esetben, ha csak a mysql pusztul ki, attól még a szerver oldali progrmnyelv lefutattja a teljes parancssorozatot, tehét a rollback megvalósul.

Az más kérdés, hogy mi történik akkor, ha az apache dob egy hátast, mert ugye akkor nem marad senki aki elemzné az adatbázis kapcsolatból származó adatokat, de pont ezért szinte 100% biztos, hogy nem történik változás. Valószínüleg marad egy töredék ideiglenes tábla az előkészített adatokkal és a mysql szerver idővel kikukázza.

Valami ilyesmit gondolok, ha nem így van, hallgassuk mit mondanak az okosabbak! :)

s_volenszki
2

Próba

vbence · 2007. Jún. 18. (H), 13.57
Gyakorlati ismeretem nem sok van a témáról, de én annak idején úgy tanultam, hogy pontosan azért találták a tranzakciót, hogy ha elszállna a rendszer két összetartozó művelet között (az egyik számláról már leemelték a pénzt, de a másikon még nem írták jóvá).
Az, hogy a MySQL mit csinál nemtudom, de úgy logikus, hogy újraindítás után nyom egy rollback-et.

Szerintem végetelenül egyszerű kipróbálni az első műveletek után nyomsz egy sleep-et php-ban és kihúzod a gépet a konnektorból :)
3

ACID

Hodicska Gergely · 2007. Jún. 18. (H), 14.25
Egy tisztességes adatbázis kezelőnek meg kell feleljen az ACID követleménynek, ha tranzakció kezelésről van szó. Ez garantálja, hogy ha crash van, a DB akkor is konzisztens állapotban maradjon. Általában ez úgy történik, hogy az adatok először nem a táblákba kerülnek, hanem különböző féle logokba. Amikor itt megtörtént a kiírás (fsync-kel miatt itt lehet para), akkor a DB neked már azt mondja, hogy minden oké, és ha ezután crash van még a táblába írás előtt, akkor induláskor a logok alapján az el nem mentett adatok kiírásra kerülnek. Tehát ha nem commitoltál, akkor az adatok tuti nem kerülnek be a DB-be.

Nekem ez úgy működik, hogy van egy $globalResult változóm ami alapértelmezetten true. Elindítom a tranzakciót, és minden adatbázis műveletet figyelek hogy az eredménye true-e. Ha nem, $globalResult = false;
Szerintem ez a megközelítés elég döcögős, érdemes lenne megismerkedne a kivétel kezeléssel, és/vagy megnézni a PDO-t.

Az más kérdés, hogy mi történik akkor, ha az apache dob egy hátast, mert ugye akkor nem marad senki aki elemzné az adatbázis kapcsolatból származó adatokat, de pont ezért szinte 100% biztos, hogy nem történik változás. Valószínüleg marad egy töredék ideiglenes tábla az előkészített adatokkal és a mysql szerver idővel kikukázza.
Itt az lehet érdekes, hogy ha pl. pconnectet használsz, akkor pl. MySQL esetén lehetnek gondok, de ez is függ attól is, hogy hogyan éred el. Ugyanis MySQL esetén ha pconnect van, akkor ha véget ér a script (ez lehet crash is), és nem zártad le a tranzakciót, akkor alap esetben nincs autiomatikus rollback, és ha ugyanezt a kapcsolatot egy másik PHP megkapja, akkor ha commitol, akkor az előző PHP (félkész) dolgai is commitolódnak. Ezért mysql_* parancsok esetén ha pconnectet használ az ember, akkor célszerű kapcsolódáskor egy rollbacket kiadni. PDO pl. ezt az esetet is lekezeli.


Üdv,
Felhő
4

Exception

kris7topher · 2007. Jún. 18. (H), 17.38
Nah igen, PDO val könnyű az élet... Mert akkor pl. elég egy try..cath-ben elkapni a PDOException-t és Rollbackelni.
Az mondjuk más kérédés, hogy érdemes-e pconnectelni, talán nagyon ritkán van olyan feladat, ahol hasznos, de a legtöbb esetben a sima connect jobb megoldás lehet pont az ilyen anomáliák miatt.
5

PDO

s_volenszki · 2007. Jún. 18. (H), 21.35
Szia Felhő!

Hogyan tudom megnézni, van-e nekem ilyen extensönöm? Mert a próbakód azt mondja: Class 'PDO' not found. Ezt kizárólag telepíteni lehet, vagy működi úgy is mint a PhpMailer osztály, hogy include-olom?

s_volenszki
7

hátha segít

virág · 2007. Jún. 19. (K), 08.04
8

Igen, segített.

s_volenszki · 2007. Jún. 19. (K), 08.16
Köszönöm szépen, a cikk alapján úgy gondolom (a C nyelv miatt), hogy egy a szerverre telepített extensönről van szó!

Köszike, s_volenszki
6

Kipróbálva ...

Max Logan · 2007. Jún. 18. (H), 22.54
Szerintem végtelenül egyszerű kipróbálni az első műveletek után nyomsz egy sleep-et PHP-ban és kihúzod a gépet a konnektorból :)

Tehát ha nem commitoltál, akkor az adatok tuti nem kerülnek be a DB-be.

És valóban, ha megszakítom a kapcsolatot a tranzakció közepén, akkor nem történik változás a DB-ben ...