A jdbc elmélet II. rész

Kapcsolattartás az adatbázissal

A program és az adatbázis közötti kapcsolatot a Connection objektum képviseli. Amint azt már említettem egy program egyszerre több kapcsolatot is fenntarthat ugyanazon vagy akár több különböző adatbázissal is. Egy kapcsolat a kiadott SQL utasításokat és azok eredményhalmazát foglalja magába. A jelenlegi meghajtó-programoktól már elvárható, hogy többszálúan valósítsanak meg egy kapcsolatot, vagyis azonos kapcsolaton belül kiadott több SQL utasítás feldolgozásának párhuzamosítása már nem a programozó, hanem a meghajtó-program feladata.

Adatbázis URL-ek

Az adatbázissal való kapcsolat létrehozásánál kérdések sorozata merülhet fel:

           hol található az interneten az a számítógép, amely az adatbázist tartalmazza?

           melyik porton hallgatja az RDBMS a kéréseket?

Az Internet ezt a problémát az URL-ek (Uniform Resource Locator) bevezetésével oldotta meg, amelynek a következő a felépítése: protokoll://hostnév:port/útvonal. Az URL tulajdonképpen a hálózati erőforrások egységes azonosítására szolgál. Egy adatbázis-URL az elérni kívánt adatbázist jelöli ki. Az adatbázis-URL-ek szintaxisa a következő:

- jdbc:alprotokoll:adatforrás leírása, ahol:

           a protokoll neve: jdbc

           az alprotokoll nevét a megfelelő meghajtó-program forgalmazója határozza meg, ezért rendszerint megegyezik a forgalmazó nevével. Egyedüli kivétel az odbc alprotokoll, amely ODBC meghajtó-program és a JDBC-ODBC áthidaló-program használatát írja elő

           az adatforrás leírása pedig a két adatbázis eléréséhez szükséges további adatokat (pl. adatbázis neve és a hálózat címe, a felhasználó neve és jelszava) tartalmazza. Ezen adatok megadásának konkrét szintaxisát szintén a meghajtó-program forgalmazója határozza meg.

Kapcsolat felvétele

A kért adatbázistípushoz tartozó meghajtó-programnak fel kell tudnia ismerni az URL alapján, hogy rá van-e szükség a kijelölt adatbázissal való kommunikáció lebonyolításához. Ha több driver van betöltve a különböző adatbázisok eléréséért akkor feltevődik a kérdés, hogy hogyan válasszuk ki a megfelelő drivert az aktuális csatlakozáshoz.  Ez  a kérdés a DriverManager osztály segítségével tisztázódik. Az adatbázis-kapcsolat felvételének szokásos menete a DriverManager getConnection metódusának meghívása, amelynek paramétere a kívánt adatbázis URL cím és esetleg egy felhasználó azonosító és jelszó. Ekkor a DriverManager sorban megnézi, hogy a regisztrált meghajtó-programok közül melyik tudja a kapott adatbázis-URL-t feldolgozni.  Például egy Oracle driver azonnal észlelné, ha egy más adatbázissal akarsz dolgozni és visszautasítaná a kérést. A DriverManager meghívja a connect metódusát az első olyan meghajtó-programnak, amely a kapott adatbázis-URL-t fel tudja dolgozni. A keresés sorrendje a meghajtó-programok regisztrációs sorrendjével egyezik meg, ahol a jdbc.drivers rendszerparaméterben megadott meghajtó-programok megelőznek minden közvetlenül regisztrált meghajtó-programot.

A DriverManager biztonsági okokból egy adott programnak csak olyan meghajtó-program használatát engedélyezi, amely lokális gépen helyezkedik el, vagy ugyanarról a címről kerül letöltésre, mint ahonnan maga a program is. Ugyanakkor a DriverManager megkerülhető, ha közvetlenül a kívánt meghajtó-program connect metódusának direkt meghívásával vesszük fel a kapcsolatot.

A kapcsolat létrejöttekor egy Connection típusú objektum hozódik létre. A Connection tulajdonképpen egy interfész, amely biztosítja a kérések eljutását az adatbázishoz és a válaszok megérkezését az adatbázistól. Az interfész metódusokat szolgáltat ahhoz, hogy információkat kapjunk az adatbázisról, bezárja az adatbázissal való kapcsolatot és lehallgatja az adatbázistól visszaérkező üzeneteket. Ugyancsak a Connection interfész tartalmazza a createStatement metódust is, amely egy Statement objektumot hoz létre a következő parancs által:

                        Statement stmt = con.createStatement();

Információ a kapcsolatról

Egy adott adatbázis minden jellemzőjéről információt a DatabaseMetaData interférsz felhasználásával lehet lekérdezni. Az adatbáziskapcsolat adatbázisát leíró objektumot a getMetaData metódussal lehet megkapni. A lekérdezett információk egy része táblázatszerű, ezeket az SQL lekérdező utasítások eredményeit is reprezentáló eredménytábla – ResultSet – osztály egy példánya fogja tartalmazni. Az információk egy része adott SQL fogalmak adatbázis-specifikus megvalósítását/korlátait adják vissza (pl. mi a katalógusszeparátor karakter, vagy egy index maximum hány oszlopból állhat stb.). Az ezeket lekérdező metódusok nevei mindig a get szócskával kezdődnek. Az információk másik része pedig azt adja meg, hogy az adott adatbázis képes-e valamilyen művelet végrehajtására (pl. ismeri-e a külső join fogalmát stb.). Ezen metódusok nevei mindig a supports szóval kezdődnek.

Tranzakciókezelés

Egy másik fontos dolog, ami ide tartozik az a tranzakciókezelés. Egy tranzakció SQL utasítások végrehajtásából áll, melyek eredményét vagy véglegesítjük az adatbázisban (a commit metódussal), vagy egyszerűen visszavonjuk minden változtatását (a rollback metódussal), visszaállítva ezzel az adatbázis eredeti állapotát. Így a tranzakció addig tart, amíg le nem zárjuk a commit vagy a rollback metódusok valamelyikét. Ezután automatikusan megkezdődik a következő tranzakció.

Egy új adatbázis-kapcsolat alapértelmezés szerint automatikusan nyugtázási móddal jön létre, azaz minden SQL utasítás befejeződése után automatikusan meghívódik a commit metódus. Egy rollback-el az utolsó commit-ig tudjuk visszacsinálni a dolgokat. Egy SQL utasítás akkor fejeződik be, ha teljesen végrehajtódott és nem ad vissza eredményt, vagy ha az SQL utasítást tartalmazó SQL objektumot újra végrehajtjuk. Eredménytáblát visszaadó SQL utasítás pedig akkor fejeződik be, ha már az eredmény utolsó sorát is feldolgoztuk, vagy ha az eredménytáblát (ResultSet) egyszerűen lezárjuk. Ha az automatikus nyugtázási módot kikapcsoljuk (a setAutoCommit metódussal), akkor a programnak magának kell vezérelnie a tranzakció-kezelést a commit és a rollback metódusok segítségével.

Tranzakció izolációs szintek

Egy többfelhasználós adatbázis-kezelő rendszer esetén előfordulhat, hogy az egyidejűleg futó tranzakciók valamilyen módon zavarják egymást. Például, ha az egyik tranzakció olyan értéket akar olvasni, amit egy másik tranzakció megváltoztatott, de még nem véglegesített, akkor milyen értéket adjon vissza az adatbázis? Ilyen és ehhez hasonló konfliktusok megoldására szolgálnak a tranzakció-izolációs szintek, melyek tulajdonképpen azt szabályozzák, hogy az adatbázis hogy viselkedjen hasonló problémák fellépésekor.

A Connection interfész öt ilyen tranzakció-izolációs szintet definiál:

           TRANZACTION-NONE – nincs tranzakciókezelés

           TRANZACTION-READ-UNCOMMITED – olvasáskor mindig az aktuális értéket kapjuk

           TRANZACTION-READ-COMMITED – olvasáskor csak a véglegesített adatokat kapjuk

           TRANZACTION-REPEATABLE-READ – a tranzakció ideje alatt az általa olvasott értékek más véglegesített tranzakciók esetleges módosító hatása ellenére is mindig megegyeznek a tranzakció kezdetekor érvényben lévő értékekkel

           TRANZACTION-SERIALIZABLE – a tranzakció ideje alatt az általa olvasott értékeket más tranzakciók nem írhatják felül

A fenti sorrend megegyezik a szintek sorrendjével, ahol az első a legalacsonyabb tranzakció-izolációs szint. Minél magasabb a szint, annál lassúbb lesz az SQL végrehajtása, mivel az adatbázis-kezelő rendszernek annál több adminisztrációt kell elvégeznie minden művelet végrehajtása során. Ezeket a szinteket a setTranzactionIzolation metódussal lehet beállítani. A szint megváltoztatása tranzakció során nem ajánlott, mivel a változtatás előbb automatikusan véglegesíti az aktuális tranzakciót, csak utána változik meg valójában az izolációs szint.

Hibakezelés

Elhagyhatatlan dolog a hibakezelés. Ha az adatbázis kapcsolat során bármilyen hiba történne, akkor egy SQLException kivétel fog kiváltódni. Ez a kivétel a fellépett hibákról a következő információkat tartalmazza:

           hiba szövegét, melyet a getMessage metódussal lehet lekérdezni

           az X/OPEN SQLstate konvencióban meghatározott SQLstate szöveget

           a hiba kódját. Ez meghajtó-program függő és rendszerint az adatbázis által visszaadott hibakódnak felel meg

           hivatkozást a következő SQLException-ra. Ezzel lehet az aktuális hibaüzenetekhez hozzárendelt esetleges kiegészítő információkat kezelni

Az előforduló figyelmeztetések lekezelését az SQLWarning kivételosztály végzi. Ilyen kivételek nem szakítják meg a program futását, mert a megfelelő metódusok maguk elkapják és az aktuális objektumhoz láncolják azokat. A fellépő figyelmeztetéseket a getWarnings metódussal lehet lekérdezni, míg a clearWarnings metódussal lehet törölni. Lekérdezéskor mindig az első figyelmeztető üzenetet kapjuk ehhez láncba van felfűzve a többi üzenet.

A kapcsolat lezárása

A kapcsolat lezárása a close metódus használatával történik. A close metódus felszabadítja az adatbázis-kapcsolat által lefoglalt JDBC erőforrásokat. Ez a metódus a kapcsolatobjektum megsemmisítésekor és bizonyos fatális hibák fellépésekor automatikusan is meghívódik.

Finta Anna Mária