C# - Adatbázis kapcsolatok beépített menedzselése

Connection Pooling

forráskód letöltése
Cikkünkben bemutatjuk, hogyan kezeli a .NET azokat az eseteket, melyekben egyetlen adatbázis kapcsolat objektumot használ valamennyi adatbázis művelet, vagyis hogyan történik ezek menedzselése. A cikk második felében ejtünk néhány szót az MS SQL Server beépített eszközéről, az SQL Profiler-ről, melynek segítségével nyomon követhető a vizsgálni kívánt adatbázissal kapcsolatos valamennyi művelet, a kapcsolódástól a kapcsolat megszűnéséig.
A példához szükséges a TestDb adatbázis, melyet a mellékelt TestDb.sql parancsállomány lefuttatásával hozhatunk létre. A TestDb.sql script 5. sorában adja meg helyesen a létrehozandó adatbázisfájlok mappájának nevét és elérési útvonalát.
„Connection Pooling”
Az adatbázis kapcsolat egy kritikus, drága és igen korlátozott erőforrás, különösen a többrétegű alkalmazások esetén. Elengedhetetlen, hogy alkalmazásainkban megfelelően kezeljük ezeket az erőforrásokat, hiszen a szemlélet, ahogyan ezt megvalósítjuk, kihat az egész alkalmazás skálázhatóságára.
Ennek hatékony megvalósításáról a rendszer beépített módon gondoskodik, bizonyos feltételek teljesülése esetén. Nevezhetjük kapcsolat menedzsmentnek (Connection Pooling). Ennek használatával lehetővé válik, hogy alkalmazásainkban újra felhasználjunk egy már létező adatbázis kapcsolatot a menedzselt gyűjteményből, ahelyett hogy egy újat létesítenénk az adatbázissal. Ez növeli az alkalmazás hatékonyságát, mivel a korlátozott számú adatbázis kapcsolattal sokkal több felhasználói kérés kiszolgálható, lévén, hogy kevésbé terheljük az illető adatbázist. Elkerülhető ugyanis az új kapcsolat felépítéséhez szükséges időráfordítás.
Amennyiben az MS SQL Server .NET Data Provider-t, mint adatelérési szolgáltatást használjuk – ahogy tesszük ezt példánkban is -, akkor a kapcsolatmenedzselést a szolgáltatás beépített módon bocsátja rendelkezésünkre. A beépített szolgáltatás igen hatékony, továbbá támogatja a tranzakció kezelést is. Mindez menedzselt kódok esetén igaz. Minden process-hez létrehoz egy kapcsolat gyűjteményt (pool), és addig nem szünteti meg, amíg az adott process nem terminál. A megfelelő konfiguráció csak a feladatunk.
Konfiguráció
A kapcsolat gyűjtemény beépített menedzseléséhez meg kell adnunk bizonyos adatokat a kapcsolatot reprezentáló SqlConnection ConnectionString property-jében. A menedzselés (pooling) alapértelmezett beállításban engedélyezve van, ez azonban letiltható. A megadott paraméterek név-érték párok, melyek tartalmazzák a kapcsolatok minimális, illetve maximális számára vonatkozó információkat, valamint egyéb adatokat. A megadható attribútumok listája a következő táblázatban látható, melyekkel a „pooling” eltérő viselkedésekre késztethető:
Név Alapértelmezett érték Leírás
Coonection Lifetime 0 Egy adott kapcsolat, miután az alkalmazás egy adott művelete felhasználta, az visszatér a gyűjteménybe, ahol a létrehozás időpontja összehasonlításra kerül az aktuális időponttal, és ha a különbség megegyezik az attribútumban specifikálttal, akkor a kapcsolat elpusztul. Nulla esetén a kapcsolat élettartalmára az alapértelmezett TIMEOUT érték vonatkozik.
Connection Reset TRUE Meghatározza, hogy a kapcsolat a menedzselt gyűjteményből kikerülve alaphelyzetbe álljon-e. Az MS SQL Server 7.0 verzióban ajánlatos ezt FALSE értékre állítani.
Max Pool Size 100 A gyűjteménybe kerülő maximális kapcsolatok száma.
Min Pool Size 0 A gyűjteménybe kerülő minimális kapcsolatok száma.
Pooling TRUE Engedélyezhetjük, vagy tilthatjuk a mechanizmust.
A fejlesztés időszakában talán annak meghatározása okoz legnagyobb gondot, hogy milyen méretűre válasszuk az adott gyűjteményt, vagyis hány kapcsolat bekerülését engedélyezzük. Ennek egzakt meghatározása elengedhetetlen, hiszen sokezres felhasználói szám esetén a konkurens kérések esetleg nem, vagy nem egy időben kerülnek kiszolgálásra. Az alkalmazás elindítása után is szükséges annak folyamatos figyelése, valamint a gyűjtemény menedzselésének ellenőrzése, hogy szükség esetén növelni tudjuk a maximális kapcsolatszámot. A maximum megválasztása függ a kiépített hardvertől is, amelyen az adatbáziskezelő rendszerünket futtatjuk.
Menedzselt kapcsolat létrehozása
A kapcsolatok egy csoportba gyűjtésekor figyelnünk kell a ConnectionString értékének megadására. Az azonos gyűjteménybe (pool) kerülő kapcsolatok teljesen azonos karakterlánccal rendelkeznek a ConnectionString property-t illetően. Ebben való bárminemű eltérés az adott kapcsolat új gyűjteménybe való kerülését idézheti elő.
Egyedi kapcsolat létrehozásakor létrejön a gyűjtemény, a kapcsolat bekerül. Újabb, azonos ConnectionString-el rendelkező kapcsolat létrehozásakor az szintén bekerül a gyűjteménybe, amíg a maximális kapcsolatszámot el nem éri.
A beérkező kérések folyamatosan felhasználják a gyűjteményben megtalálható kapcsolatokat. Amennyiben a kapcsolatok mindegyike felhasználásra került, vagyis nincs elérhető kapcsolat-objektum, akkor a beérkező kérések sorban állnak addig, míg valamely kapcsolat felszabadul. A felszabadult kapcsolatot a kérések érkezési sorrendben kapják meg. Ha a kapcsolat-objektum ConnectionTimeout property-jén keresztül megadható idő lejár, mielőtt a kérés megkapná az illető kapcsolatot, hiba keletkezik.
Ennek értelmében a kapcsolatokat használat után gondosan le kell zárni. A le nem zárt kapcsolatok nem adódnak hozzá a gyűjteményhez, illetve nem kerülnek oda vissza.
Törlés a gyűjteményből
Az egyes kapcsolatok ki is kerülhetnek a menedzselt csoportból. Ennek oka lehet, hogy lejár az adott kapcsolathoz definiált élettartam jelzőszám, vagy a kezelő algoritmus azt érzékeli, hogy az adott kapcsolatot az adatbázis szerver elbontotta. Megjegyzendő, hogy ez csak akkor derül ki, ha az adott alkalmazás megpróbál kommunikálni az adott kapcsolaton keresztül a szerverrel. Ha a kapcsolatokat menedzselő beépített algoritmus érzékeli, hogy egy kapcsolat nem él, akkor megjelöli. A kezelő bizonyos időközönként lefuttat egy ellenőrző szekvenciát annak megállapítására, hogy mely kapcsolatok élnek, és melyek nem (melyek vannak nem élőként megjelölve). A nem élő kapcsolatok törlésre kerülnek a listából.
Ha egy élő kapcsolat olyan szerverhez kapcsolódik, mely eltűnt a hálózatból (például mert lekapcsolták), akkor a kapcsolat még akkor is törlődik a gyűjteményből, ha nincs megjelölve. Ha az adott kapcsolatot lezárjuk, akkor az felszabadul, és visszakerülhet a gyűjteménybe.
Mellékelt alkalmazás
A mellékelt alkalmazásban a TestDb.sql parancsállomány lefuttatása után létrejövő adatbázissal építünk fel egy menedzselt kapcsolat gyűjteményt úgy, hogy minden, az adatbázist elérő objektum azonos ConnectionString property-vel létrehozott kapcsolatot használ. Mind a SqlDataAdapter, mind pedig a SqlCommand objektumok. A kapcsolatokat a következő karakterlánccal hozzuk létre:
connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=TestDb;Max Pool Size = 5;Min Pool Size=0;Pooling=true;");
A feladatban rekordokat szúrhatunk be a Table1 és Table2 táblákba, miközben az MS SQL Server SQL Profiler eszközével nyomon követtethetjük, hogy mi is zajlik le egy-egy művelet végrehajtásakor az adatbáziskezelő rendszerben.
SQL Profiler
A MS SQL Server SQL Profiler eszközét alapértelmezésben a "%winroot%:\Program Files\Microsoft SQL Server\80\Tools\Binn\profiler.exe" elérési útvonalon találjuk meg.
Elindítva a programot a FILE - NEW menüpontban ki kell választanunk a TRACE menüpontot egy új figyelő process indításához. A megjelenő dialógusablakban ki kell választanunk a vizsgálandó SQL Server példányt, majd a Trace Properties ablakban meg kell adnunk a vizsgálat jellemzőit. A RUN feliratú gombra kattintva a monitorozás elindul.
A megjelenő táblázatban rengeteg információt kaphatunk az éppen zajló folyamatokról, műveletekről. A kapcsolat felépülését az Audit Login szöveg jelzi számunkra, közölve a kapcsolódó alkalmazás nevét (vagyis az osztály nevét: .NET SQL Data Provider), a bejelentkezett felhasználó nevét, a művelet időpontját, valamint a kapcsolatnak a használt erőforrásokra vonatkozó információit.
A táblák valamelyikébe történő adatbevitel esetén a TextData oszlopban látható a végrehajtódó SQL utasítás. A kapcsolat befejezését az Audit Logout esemény megjelenése jelzi.