HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Cache-re helyezett SQL tábla adatainak módosulásakor a Cache automatikus érvénytelenítése


Példaprogram letöltése

15575 bájt

Amikor a Cache-re adatot helyezünk, akkor annak törlését vagy manuálisan kell elvégeznünk, vagy köthetjük egy állomány megváltozásához, de megadhatunk lejárati időt is, viszont nincs olyan lehetőség, mely egy SQL tábla tartalma megváltozásakor törölné a Cache-re helyezett adatainkat. Márpedig, ha a Cache-n tárolunk egy adattáblából származó adathalmazt és az változik valamilyen módon (insert, update, delete), akkor frissíteni kellene a Cache-t is. Erre megoldás lehet, hogy minden adatmódosítás elvégzésekor érvénytelenítjük a Cache-t. Ezzel csak akkor lesz baj, ha véletlenül elfelejtjük megtenni ezt a lépést, vagy több alkalmazás is használja ugyanazt az adattáblát. Sokkal jobb lenne egy olyan megoldás, mely teljesen automatikusan érvényteleníti a Cache tartalmát, amikor Insert, Update, vagy Delete művelet kerül végrehajtásra az adott táblán. Mellékelt példában erre keresünk megoldást.

Mellékelt példa megnyitása előtt szükséges egy InvalidateCache nevű virtuális könyvtár létrehozása, mely a mellékelt példa könyvtárára mutat. Ehhez nyissa meg a mellékelt mappa Tulajdonság ablakát és itt a Webmegosztás lapon engedélyezze a mappa megosztását olvasási és parancsfájlok futtatási jogával.
A példaprogram kipróbálásához a következő lépésekre van szükség annak lefordítása előtt:
  • A mellékelt InvalidateCache.sql-t nyissa meg szerkesztésre és a 97. sorában lévő „s” változó értékét módosítsa úgy, hogy az a mellékelt DelCache.exe-re mutasson.
  • Futtassa le az InvalidateCache.sql-t, hogy létrejöjjön az MS SQL adatbázis.
  • A WebForm1.cs forráskód 26. sorában lévő connStr változót módosítsa úgy, hogy elérhetővé váljon az InvalidateCache adatbázis.
  • A WebForm1.cs forráskód 27. sorában lévő txtFile változót módosítsa úgy, hogy az a mellékelt DelCache mappában lévő Cache.txt-re mutasson.
Ezek után a mellékelt példaprogram futtatható.
A program működési elve a következő: a WebForm1 megjelenésekor futtatunk egy lekérdezést egy SQL táblára. Ennek eredményét tároljuk a Cache-n, így a következő megjelenítéskor már nincs szükség az SQL adatbázis elérésére és az adatokat a Cache-ről vehetjük elő. Az adott táblához létrehozunk egy triggert, mely fut az insert, update és delete műveletek esetén is. Ez a trigger meghív egy másik EXE alkalmazást, melyet a mellékelt DelCache mappában helyeztünk el. Ez a program módosítja a Cache.txt tartalmát. Az ASP.NET-es alkalmazásunkban úgy helyeztük el a Cache-re az adatokat, hogy az ettől a Cache.txt-től függjön. Így amikor fut a trigger, mert módosult az adattábla, akkor változni fog az az állomány is, mely érvényteleníti a Cache-t, így egy következő kéréskor már nem lesz elérhető a Cache-en az adat, melyet ekkor egy újabb lekérdezéssel kell előállítani.
Ezzel a módszerrel nincs gondunk arra, hogy hány helyen is módosulhat a tábla, vagy hány program használja azt. Bármilyen módon is történjen a változás biztos, hogy a Cache érvénytelenítésre kerül, így egy újabb kérésnél egy ismételt lekérdezéssel mindig a legfrissebb adatokat láthatja a felhasználó.
Amennyiben változik a Cache.txt állomány, de ennek ellenére a Cache nem törlődik, akkor módosítsuk az alapértelmezésben a C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\CONFIG könyvtárban lévő machine.config állományban a processModel bejegyzésnél a userName attribútumot system értékre, majd indítsuk újra a számítógépet.
Kell tehát két projektet készítenünk: egyet, mely változtatja a Cache-t és magát az ASP.NET-es alkalmazást, mely megjeleníti az adatokat.
Ezek előtt azonban nézzük meg magát a triggert, mely gondoskodik majd az programunk meghívásáról:
CREATE TRIGGER DelCache ON [dbo].[Table1] 
FOR INSERT, UPDATE, DELETE 
AS
begin
  DECLARE @s VarChar(100)
  SET @s = 'F:\So\Cso\0230\InvalidateCache\DelCache\DelCache.exe '
  EXEC Master..xp_cmdshell @s
end
A triggert mind az insert, update és delete műveletekhez is létrehozzuk, így minden módosító hatású eseményt figyelni tudunk. Ha ez bekövetkezik, akkor futtatjuk a Master adatbázisban lévő xp_cmdshell tárolt eljárást, mely képes arra, hogy egy tetszőleges programot elindítson. Paraméterként megadjuk neki a DelCache.exe alkalmazásunkat.
DelCache projekt
Készítsünk egy egyszerű konzol alkalmazást, melyet meghívhat a trigger. Ennek egyetlen egyszerű feladata lesz, hogy változtassa a Cache.txt állomány tartalmát. Még az is teljesen mindegy, hogy mit tartalmaz ez az állomány, mert a Cache szempontjából csak a változás ténye lesz a kérdéses. Az egyszerűség kedvéért írjuk az állományba az aktuális időpontot.
    static void Main(string[] args)
    {
      FileStream fs = new FileStream(Application.StartupPath+"\\Cache.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
      StreamWriter sw = new StreamWriter(fs);
      sw.Write(DateTime.Now.Ticks.ToString());
      sw.Flush();
      sw.Close();
    }
InvalidateCache projekt
Nézzük most miként is jön létre a webes alkalmazásunk. Amikor a lap betöltésre kerül, akkor vizsgáljuk, hogy a Cache-en megtalálható-e már a CacheTable nevű objektum.
    private void Page_Load(object sender, System.EventArgs e)
    {    
      if (!IsPostBack)
      {
        DataSet ds = new DataSet();
        if (Cache["CacheTable"]==null) 
        {
Ha még nincs a Cache-re helyezve az adattábla, akkor létrehozunk egy SQL kapcsolatot és futtatunk egy egyszerű lekérdezést a Table1 nevű táblára. Ennek eredményét tároljuk a már létrehozott DataSet objektumba.
          SqlConnection connection = new SqlConnection(connStr);
          connection.Open();
          SqlDataAdapter da = new SqlDataAdapter("select * from Table1", connection);                      
          da.Fill(ds);        
A tárolt adatokat egyúttal el is helyezzük a Cache-en, hogy a következő webes kéréskor már rendelkezésre álljon és így ne kelljen újabb SQL lekérdezést futtatni. Az elhelyezendő adatokat CacheTable-nek nevezzük. Ez lesz az Insert függvény első paramétere. Másodikként magát az adathalmazt adjuk át. Végül harmadik paraméterként megadjuk a Cache.txt állományunk elérési útvonalát egy CacheDepedency objektumon keresztül. Ettől kezdve, ha változik a megadott TXT, akkor a Cache-ről automatikusan eltávolításra kerül CacheTable nevű objektum és így a következő webes kérésnél ismét csak az SQL lekérdezéses rész fut le.
          Cache.Insert("CacheTable", ds, new CacheDependency(txtFile));                                
          Label1.Text = "Az adatok SQL lekérdezés útján érhetők el.";
        } 
        else 
        {        
Ha a kérésnél a CacheTable objektum már megtalálható a Cache-en, akkor egyszerűen innen kiolvassuk és elhelyezzük az adatokat a DataSet-be.
          ds = (DataSet)Cache["CacheTable"];
          Label1.Text = "Az adatok a Cache-ből származnak.";
        } 
Végül már csak annyi a teendőnk, hogy a DataGrid-ben megjelenítsük a DataSet adatait.
        DataGrid1.DataSource = ds.Tables[0].DefaultView;
        DataGrid1.DataBind();
      }
    }
A teszt érdekében elhelyezünk egy Refresh nevű gombot a web lapon. Erre kattintva ismét a WebForm1-re ugrunk, vagyis újra betöltjük ugyanazt a lapot. Ekkor figyelve a Label1 értékét tudomást szerezhetünk arról, hogy az adatok a Cache-ről származnak-e, vagy az SQL adatbázisból. Első futtatáskor, vagy a tábla módosulásakor az SQL adatbázisból kell, hogy jöjjenek az adatok és minden más esetben a Cache-ről.
    private void Button1_Click(object sender, System.EventArgs e)
    {
      Response.Redirect("WebForm1.aspx");
    }
Hogy az adatmódosuláskor történő automatikus Cache érvénytelenítést is tudjuk tesztelni, elhelyezünk még egy nyomógombot a web lapon, melyre kattintva képesek vagyunk egy új sort felvenni a táblába. Ekkor futnia kell a triggernek, mely meghívja a másik programunkat, ami módosítja a Cache.txt-t, aminek eredményeképp a CacheTable el kell hogy tűnjön a Cache-ről. Az új sor felvétele után ismét a WebForm1.aspx lapra ugrunk, így rögtön megláthatjuk azt, hogy tényleg nem a Cache-ről jönnek-e az adatok és természetesen az újonnan felvett sornak is látszania kell.
    private void Button2_Click(object sender, System.EventArgs e)
    {
      Random r = new Random();
      SqlConnection connection = new SqlConnection(connStr);
      connection.Open();
      SqlCommand c = new SqlCommand("insert into Table1 (Data) values ('"+r.Next(Int32.MaxValue).ToString()+"')", connection);                      
      c.ExecuteNonQuery();    
      Response.Redirect("WebForm1.aspx");
    }

Könyv
Ez a cikk megtalálható ebben a könyvben: C# Software Offline 2002 évkönyv 467. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |