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

首頁 > 編程 > .NET > 正文

15秒:為ASP.NET應(yīng)用緩存Oracle數(shù)據(jù)

2024-07-10 13:04:42
字體:
供稿:網(wǎng)友

為了創(chuàng)建可擴(kuò)展、高性能的基于web的應(yīng)用,asp.net提供一個稱為數(shù)據(jù)緩存(data caching)的特性。數(shù)據(jù)緩存支持將頻繁訪問的數(shù)據(jù)對象可編程地存放在內(nèi)存中。這一特性可擴(kuò)展以廣泛地提高查詢oracle數(shù)據(jù)庫中數(shù)據(jù)的asp.net應(yīng)用的性能。本文講述一個策略,可用于采用web farm環(huán)境中的asp.net web應(yīng)用緩存oracle數(shù)據(jù)庫數(shù)據(jù)。這個技巧允許在內(nèi)存中緩存頻繁訪問的oracle數(shù)據(jù)庫數(shù)據(jù),而不是頻繁訪問數(shù)據(jù)庫來取數(shù)據(jù)。這可以幫助避免到oracle數(shù)據(jù)庫服務(wù)器的不必要的遠(yuǎn)路。進(jìn)一步的,文章提出了一個保持緩存數(shù)據(jù)以使其始終與oracle數(shù)據(jù)同步的實現(xiàn)。

asp.net中的數(shù)據(jù)緩存

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

設(shè)定緩存依賴

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

oracle數(shù)據(jù)庫上的asp.net緩存依賴

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

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

這個例子使用oracle數(shù)據(jù)庫中一個名為employee的表。我們?yōu)樵摫砩蟟nsert, update, delete設(shè)定觸發(fā)器。這些觸發(fā)器調(diào)用一個封裝了一個java存儲過程的pl/sql函數(shù)。這個java存儲過程負(fù)責(zé)更新緩存依賴的文件。

asp.net tier的vb.net實現(xiàn)

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

dim onremove as cacheitemremovedcallback = nothing

onremove = new cacheitemremovedcallback(addressof removedcallback)

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

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()負(fù)責(zé)查詢數(shù)據(jù)庫表employee并返回一個dataview對象引用。它使用一個名為getemployee的存儲過程來抽象從employee表中取數(shù)據(jù)的sql。這個方法有一個名為p_empid的參數(shù),表示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

函數(shù)getdatabaseconnection接受一個連接字符串(connection stirng)為參數(shù),返回一個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數(shù)據(jù)庫tier實現(xiàn)

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

begin

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

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

end;

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

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包裹實現(xiàn)如下。包裹函數(shù)以文件名為參數(shù),調(diào)用java存儲過程中updatefile方法。

(p_filename in varchar2)

as language java

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

web farm部署中的oracle數(shù)據(jù)緩存

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

結(jié)論

數(shù)據(jù)緩存是優(yōu)化oracle數(shù)據(jù)庫上asp.net應(yīng)用的有效技巧。盡管asp.net不允許設(shè)定緩存的數(shù)據(jù)庫依賴,oracle觸發(fā)器協(xié)同java存儲過程可以擴(kuò)展asp.net緩存的威力從而允許oracle數(shù)據(jù)庫緩存。這個技巧也可以適用于web farm部署。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 淳安县| 汤阴县| 甘肃省| 出国| 屏东市| 汉源县| 苏州市| 科技| 犍为县| 双江| 克拉玛依市| 平遥县| 蚌埠市| 崇义县| 松潘县| 襄城县| 张家川| 西乌| 尖扎县| 前郭尔| 东乌| 阜新| 江永县| 原平市| 曲阳县| 辽阳市| 南靖县| 潮州市| 高州市| 柘城县| 漳浦县| 佛学| 邵阳县| 武川县| 宁南县| 漳平市| 昭觉县| 枣庄市| 甘谷县| 志丹县| 和田市|