23. Fejezet. Állandó adatbázis kapcsolatok

Az állandó kapcsolatok SQL adatbázisokkal nem szűnnnek meg, ha a szkripted futása befejeződik. Ha egy állandó kapcsolatot kérsz, a PHP ellenőrzi, hogy van-e már megegyező kapcsolat (ami még az előző kérésekből maradhatott meg), és ha létezik, akkor azt használja. Ha nem talál ilyet, létrehoz egy kapcsolatot. A megegyező kapcsolat azt jelenti, hogy ugyanaz a host és ugyanaz a felhasználói név és jelszó került felhasználásra.

Megjegyzés: Állandó kapcsolatokat nem csak adatbázisok szolgáltathatnak, vannak más ilyen képességű kiterjesztések, mint például az IMAP kiterjesztés.

Ha esetleg nem ismered alaposabban a webszerverek működését, hibás kép alakulhat ki benned az állandó kapcsolatokról. Ezek a kapcsolatok nem alkalmasak arra, hogy felhasználói 'session'-eket nyiss ugyanazon SQL linkkel. Nem adnak lehetőséget hatékony tranzakciók felépítésére. Egészen pontosan, hogy alaposabban tisztázzuk a kérdést, az állandó adatbázis kapcsolatok nem adnak semmilyen plusz lehetőséget, ami nélkülük nem létezne.

Miért?

A válaszhoz meg kell érteni, hogyan működnek együtt a webszerverek a PHP-vel. Ennek három különböző módja lehetséges.

Az első lehetőség, hogy a PHP-t CGI "wrapper"-ként használod. Ha ezt a módszert használod, minden oldal lekérésekor és feldolgozásakor egy új példány fut le a PHP feldolgozóból. Mivel a szkript futtatása után egy ilyen példány leáll, minden erőforrás, amit lefoglalt (beleértve az adatbázis kapcsolatotokat) megszűnik. Ebben az esetben semmit sem érsz azzal, hogy állandó kapcsolatot próbálsz nyitni, ez az állandóság nem valósul meg.

A népszerűbb második forma, amikor a PHP-t modulként futtatod egy több process-es webszerverben. Egy több process-es webszerver tipikusan rendelkezik egy szülő process-el, ami koordinálja a többi kapcsolódó process (a gyermekek) munkáját, amik valójában a weboldalak kiszolgálását végzik. Ha egy kérés érkezik egy klienstől, egy éppen szabad gyermekprocess kapja meg a kiszolgálásra az utasítást. Ez azt jelenti, hogy ha ugyanaz a kliens egy újabb kapcsolatot kezdeményez, esetleg egy másik gyermekprocesshez jut, mint az első alkalommal. Ebben az esetben az állandó adatbázis kapcsolat azt jelenti a számodra, hogy az egyes gyermekprocess-ek csak az első alkalommal kell, hogy létrehozzák a kapcsolatot az adatbázissal, és amennyiben egy későbbi kérés ugyanebben a gyermekprocessben ugyanazt a kapcsoltatot kívánja megnyitni, a létező kapcsolat kerül felhasználásra.

A harmadik módszer, hogy a PHP-t plug-in-ként használod egy 'multithreaded' web szerverben. Ez azt jelenti, hogy az ISAPI, WSAPI, és NSAPI (Windows alatt) formák használhatóak a PHP-vel. Ez a PHP 4.0.0 óta lehetséges, és így a PHP alkalmas plug-in szintű együttműködésre a Netscape FastTrack (iPlanet), a Microsoft Internet Information Server (IIS), és az O'Reilly WebSite Pro szerverekkel, valamint más, a fenti standardokat támogató szerverekkel. Ebben az esetben az állandó adatbázis kapcsolatok működése megegyezik a fent leírt több process-es modellel.

Ha az állandó adatbázis kapcsolatok nem nyújtanak plusz szolgáltatásokat, mégis mire jók?

A válasz igen egyszerű: hatékonyság! Az állandó adatbázis kapcsolatok akkor lehetnek hasznosak, ha nagy a feleslegesen adatbázishoz kapcsolódással eltöltött idő. Az, hogy ez valójában milyen esetben van így, rengeteg faktoron múlik. Például azon, hogy milyen típusú adatbázisról van szó, azonos, vagy különböző gépen van-e, mint a szerver, mennyire terhelt az SQL szerver, stb. Lényegében, ha sok időt vesz igénybe a kapcsolódás, az állandó kapcsolatok jelentős segítséget nyújthatnak neked. Egy gyermekprocess így csak egy alkalommal kell, hogy kapcsolódjon, ahelyett, hogy egy ezt kérő oldal minden feldolgozásakor megtenné. Ez azt is jelenti, hogy minden gyermekprocessnek, meglesz a maga állandó kapcsolata a szerver felé. Például, ha 20 különböző gyermekprocess dolgozott fel egy állandó adatbáziskapcsolatot kérő oldalt, 20 különböző állandó kapcsolatod lesz az SQL szerverhez, egy-egy minden gyermektől.

Fontos megjegyezni azonban, hogy ennek lehetnek hátrányos következményei is, ha az adatbázisszerver korlátozott kapcsolatainak számát az állandó kapcsolatok lefoglalják. Ha az adatbázisszervered egyidejűleg maximálisan 16 kapcsolatot képes kezelni, és egy forgalmas időszakban egyszerre 17 process próbál meg kapcsolódni az adatbázishoz, az egyik képtelen lesz erre... Ha olyan hiba van a programodban (például végetelen ciklus), ami nem hagyja a kapcsolat felbontását, egy csak 32 kapcsolattal bíró adatbázis alaposan le lesz foglalva. Nézz utána az adatbázisszervered dokumentációjában, hogy hogyan tudod lekezelni az elhagyott vagy inaktív kapcsolatokat.

Figyelem

Van még néhány faktor, amit érdemes figyelembe venned, ha állandó adatbázis kapcsolatokat használsz. Egy ilyen probléma, hogy ha tábla lezárást (lock) használsz egy állandó kapcsolaton, és a szkript valamilyen okból nem tudja feloldani a zárat, ezt a kapcsolatot használó további szkriptek nem fognak helyesen működni, és a webszerver vagy adatbázis szerver újraindítására lehet szükség a feloldáshoz. Hasonlóan ha tranzakciókat használsz, a tranzakció blokk tovább folytatódik a következő megegyező kapcsolatot használó szkriptben, ha a tranzakciót indító szkript nem tudja lezárni azt. Ezekben az esetekben a register_shutdown_function() függvényt használhatod, hogy egy egyszerű "takarító" függvényt futtass le a programod végeztével, ami visszavonja a tranzakciókat, és feloldja a tábla zárakat. Jobban teszed azonban, ha úgy kerülöd meg a problémát, hogy nem használsz állandó kapcsolatokat olyan szkriptekben, amik tábla zárakat, vagy tranzakciókat alkalmaznak.

Összefoglalva: az állandó adatbáziskapcsolatokat úgy tervezték, hogy megfeleltethetőek legyenek a hagyományos kapcsolatokkal. Ez azt jelenti, hogy minden esetben lehetőséged van az állandó kapcsolatokat hagyományos kapcsolatokra cserélni, és ez nem fogja megváltoztatni a szkriptjeid működését. Ez a lépés megváltoztathatja a szkripted hatékonyságát, de a viselkedését nem!

Lásd még fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), imap_popen(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), OCIPLogon(), odbc_pconnect(), Ora_pLogon(), pfsockopen(), pg_pconnect(), és sybase_pconnect().