国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

ASP.NET應用中緩存Oracle數據

2024-07-10 13:04:35
字體:
來源:轉載
供稿:網友
為了創建可擴展、高性能的基于web的應用,asp.net提供一個稱為數據緩存(data caching)的特性。數據緩存支持將頻繁訪問的數據對象可編程地存放在內存中。這一特性可擴展以廣泛地提高查詢oracle數據庫中數據的asp.net應用的性能。本文講述一個策略,可用于采用web farm環境中的asp.net web應用緩存oracle數據庫數據。這個技巧允許在內存中緩存頻繁訪問的oracle數據庫數據,而不是頻繁訪問數據庫來取數據。這可以幫助避免到oracle數據庫服務器的不必要的遠路。進一步的,文章提出了一個保持緩存數據以使其始終與oracle數據同步的實現。

  asp.net中的數據緩存

  asp.net中的數據緩存由cache類和system.web.caching命名空間中的cachedependency類支持。cache類提供向緩存插入和從中取出數據的方法。cachedependency類允許為緩存中數據項的指定其依賴項。當我們用insert和add方法將項目加入緩存中,可以指定一個項目的過期(expiration)策略。我們可以用insert方法的absoluteexpiration屬性來定義緩存中一個項目的生命期。這個屬性允許你指定相應數據項過期的準確時間。也可以使用slidingexpiration屬性來指定項目過期的流逝時間(基于它被訪問的時間)。一旦一個項目過期,它從緩存中被清除。除非它再次被加入緩存中,否則再試圖訪問,將返回一個空值。

  設定緩存依賴

  asp.net使我們可以基于一個外部文件、目錄或另一個緩存項來定義一個緩存項的依賴,即所謂文件依賴與鍵依賴。若一個依賴項改變,緩存項自動失效并被從緩存中清除。當相應的數據源改變時,我們可以用這種方法來從緩存中刪除項目。例如,若我們的應用從一個xml文件中取數據并顯示在一個表格(grid)中,我們可以把文件中的數據存放到緩存中,并設定緩存依賴于那個xml文件。當xml文件被更新,數據項就從緩存中被清除出去。這一事件發生時,應用重新讀入xml文件,最新的數據項副本被再一次插入緩存中。進一步的,回調事件處理器可被設定為一個監聽者,當緩存項被刪除時得到通知。這使得我們不需要反復輪詢緩存來確定數據項是否已無效。

oracle數據庫上的asp.net緩存依賴

  現在考慮這樣一個情景:數據存放于oracle數據庫中,一個asp.net應用通過ado.net來訪問。進一步,我們假設數據庫表中的數據一般是靜態的,并被這個web應用頻繁訪問。表上的dml操作很少而對數據有很多select。這種情況是數據緩存技術的理想應用。但不幸的是,asp.net并不允許設定一個緩存項依賴于存放在數據庫表中的數據。進一步,現實世界中,基于web的系統,web服務器和oracle數據庫服務器總是會運行在不同的機器上,使得緩存無效操作更有挑戰性。另外,多數基于web的應用采用web farms,同一個應用的實例在不同的web服務器上跑以負載均衡。這種情況使得數據庫緩存問題稍稍復雜一些。

  為了進一步研究上述問題的解決方案,我們舉一個web應用的例子來說明如何實現。例子中,我們使用vb.net實現的asp.net應用,通過oracle data provider for .net (odp)來訪問 oracle 9i數據庫。

  這個例子使用oracle數據庫中一個名為employee的表。我們為該表上insert, update, delete設定觸發器。這些觸發器調用一個封裝了一個java存儲過程的pl/sql函數。這個java存儲過程負責更新緩存依賴的文件。

  asp.net tier的vb.net實現

  我們設計了含一個回調方法的監聽類來處理緩存項無效時的通知。這個回調方法removedcallback用一個代理(delegate)函數來注冊。回調方法onremove的聲明必須與cacheitemremovedcallback代理聲明又相同的簽名。

dim onremove as cacheitemremovedcallback = nothing
onremove = new cacheitemremovedcallback(addressof removedcallback)

  監聽事件處理方法removedcallback負責處理數據庫觸發器的通知,其定義如下。若緩存項失效,可用數據庫方法調用getrecordfromdatabase()從數據庫取出數據。參數”key”指從緩存中刪除的項的索引位置。參數”value”指從緩存中刪除的數據對象。參數"cacheitemremovedreason"指從緩存中刪除數據項的原因。

publicsub removedcallback(byval key asstring, byval value asobject, byval reason as cacheitemremovedreason)

 dim source as dataview
 source = getrecordfromdatabase()
 cache.insert("employeetable ", source, new
 system.web.caching.cachedependency("d:/download/tblemployee.txt"),
 cache.noabsoluteexpiration, cache.noslidingexpiration,
 cacheitempriority.normal, onremove)

endsub  

  方法getrecordfromdatabase()負責查詢數據庫表employee并返回一個dataview對象引用。它使用一個名為getemployee的存儲過程來抽象從employee表中取數據的sql。這個方法有一個名為p_empid的參數,表示employee的主鍵。

publicfunction getrecordfromdatabase (byval p_empid as int32) as dataview

 dim con as oracleconnection = nothing
 dim cmd as oraclecommand = nothing
 dim ds as dataset = nothing

 try
  con = getdatabaseconnection( "userid=scott;password=tiger;data source=testingdb;")
  cmd = new oraclecommand("administrator.getemployee", con)
  cmd.commandtype = commandtype.storedprocedure
  cmd.parameters.add(new oracleparameter("employeeid", oracledbtype.int64)).value = p_empid
  dim param asnew oracleparameter("rc1", oracledbtype.refcursor)
  cmd.parameters.add(param).direction = parameterdirection.output
  dim mycommand asnew oracledataadapter(cmd)
  ds = new dataset
  mycommand.fill(ds)
  dim table as datatable = ds.tables(0)
  dim index as int32 = table.rows.count
  return ds.tables(0).defaultview
 catch ex as exception
  thrownew exception("exception in database tier method getrecordfromdatabase () " + ex.message, ex)

 finally

  try
   cmd.dispose()
  catch ex as exception
  finally
   cmd = nothing
  endtry
  try
   con.close()
  catch ex as exception
  finally
   con = nothing
  endtry
 endtry
endfunction

  函數getdatabaseconnection接受一個連接字符串(connection stirng)為參數,返回一個oracleconnection對象引用。

publicfunction getdatabaseconnection(byval strconnection as string) as oracleconnection
 dim con as oracle.dataaccess.client.oracleconnection = nothing
 try
  con = new oracle.dataaccess.client.oracleconnection
  con.connectionstring = strconnection
  con.open()
  return con
 catch ex as exception
  thrownew exception("exception in database tier method getoracleconnection() " + ex.message, ex)
 endtry
endfunction

  oracle數據庫tier實現

  定義employee表上dml事件的觸發器體如下。這個觸發器簡單的調用一個pl/sql包裹函數來更新名為tblemployee.txt的操作系統文件。文件副本在兩臺機器(機器1和機器2)上更新。兩臺機器運行同一個web應用的不同實例來均衡負載。這里administrator指oracle數據庫的方案(schema)對象所有者。

begin
 administrator.plfile('machine1//download// tblemployee.txt');
 administrator.plfile('machine2//download// tblemployee.txt');
end;

  為更新緩存依賴文件,我們需要寫一個c函數或java存儲過程。我們的例子中選擇了java存儲過程,因為oracle數據庫服務器有一個內置的jvm,使得書寫java存儲過程很方便。必須有足夠的內存分配給oracle實例的系統全局區(sga)中的java池。靜態方法updatefile接受一個絕對路徑作為參數,并在合適的目錄中創建緩存依賴文件。若文件已經存在,則先刪除然后創建。

import java.io.*;

public class updfile {public static void updatefile(string filename)
{
 try {
  file f = new file(filename);
  f.delete();
  f.createnewfile();
 }
 catch (ioexception e)
 {
  // log exception
 }

};

  pl/sql包裹實現如下。包裹函數以文件名為參數,調用java存儲過程中updatefile方法。

(p_filename in varchar2)

as language java

name 'updfile.updatefile (java.lang.string)';

  web farm部署中的oracle數據緩存

  正如我們討論的例子中所示,web服務器1和機器2構成了一個web farm來為我們的web應用提供負載均衡。每臺機器運行同一個web應用的一個實例。在這個情況下,每個實例可以擁有自己的存放在cache對象中的緩存數據副本。當employee表改變,相應的數據庫觸發器更新兩臺機器上的文件tblemployee.txt。每個實例都指定一個到tblemployee.txt的緩存依賴,web farm的兩個實例都可以正確更新,使得兩個實例上的數據緩存可以和數據庫表employee保持同步。

  結論

  數據緩存是優化oracle數據庫上asp.net應用的有效技巧。盡管asp.net不允許設定緩存的數據庫依賴,oracle觸發器協同java存儲過程可以擴展asp.net緩存的威力從而允許oracle數據庫緩存。這個技巧也可以適用于web farm部署。

最大的網站源碼資源下載站,

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 湘阴县| 上饶市| 集贤县| 镇江市| 临颍县| 高邑县| 印江| 聂荣县| 桐梓县| 十堰市| 太仆寺旗| 白沙| 武宁县| 新宾| 怀宁县| 安达市| 边坝县| 班玛县| 维西| 浪卡子县| 建昌县| 兰溪市| 宁化县| 濮阳县| 菏泽市| 宁海县| 麻江县| 南漳县| 那坡县| 安庆市| 无极县| 南城县| 泾川县| 南昌市| 弥勒县| 石嘴山市| 静安区| 黑河市| 周至县| 万安县| 大石桥市|