为ASP.NET应用缓存Oracle数据

asp.net|oracle|缓存|数据

为了创建可扩展、高性能的基于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部署。

时间: 2024-08-30 19:33:06

为ASP.NET应用缓存Oracle数据的相关文章

oracle11g-使用的ASP.NET,操作ORACLE数据时,在VS中执行的效果和PL中不一样

问题描述 使用的ASP.NET,操作ORACLE数据时,在VS中执行的效果和PL中不一样 简单说来就是我有一个表A,我向其中插入数据,用最简单的方式insert into A values(aa='aa',bb='bb'),在VS中会报出"关于ora-00942: 表或视图不存在"这个错误,将这个SQL语句原封不动的copy到PL里面,就能实现.还有就是我select * from A,在VS中执行得不到任何数据,但是在PL中能得到4行数据,与真实情况吻合,求解是什么情况... 解决方

ASP实现Oracle数据记录的分页显示程序

oracle|程序|分页|数据|显示 本文仔细的阐述了利用ASP实现Oracle数据记录的分面显示步骤. 一.引言 通过浏览器访问数据量大的表时需要进行分页.ASP对数据库记录分页显示可以通过ADO对象集Recordset对象来实现.Recordset具有以下几个用于分页显示的属性: PageSize:每页显示的记录数. PageCount:根据用户设定好的PageSize和表中的总记录数,系统自动算出总页数.RecordCount:表中的总记录数. AbsolutePage:表示当前页码.如将

利用ASP实现Oracle数据记录的分页显示

oracle|分页|数据|显示 一.引言 通过浏览器访问数据量大的表时需要进行分页.ASP对数据库记录分页显示可以通过ADO对象集Recordset对象来实现.Recordset具有以下几个用于分页显示的属性: PageSize:每页显示的记录数. PageCount:根据用户设定好的PageSize和表中的总记录数,系统自动算出总页数.RecordCount:表中的总记录数. AbsolutePage:表示当前页码.如将AbsolutePage属性设为3,则当前记录移至第3页第1条(也就是第3

asp.net C连接oracle数据库并显示数据

asp教程.net c连接oracle数据库教程并显示数据 本款是是由asp.net教程 与oracle数据库连接,并且显示数据中的所有数据哦. data source=torcl;user id=myusername;password=mypassword; data source=(description=(address_list=(address=(protocol=tcp)(host=myhost)(port=myport)))(connect_data=(server=dedicat

艾伟_转载:ASP.NET数据缓存之数据缓存浅谈

ASP.NET数据缓存的学习是如何呢?如何使用ASP.NET数据缓存呢?在讲ASP.NET数据缓存之前还要先说一下如果在页面中使用参数缓存.前面讲过一个缓存设置VaryByParam="none"为无参数,我们也可以对VaryByParam进行设置,设置的参数与随 GET 方法属性发送的查询字符串值对应,或与使用 POST 方法发送的参数对应.将该属性设置为多个参数时,对于每个指定参数组合,输出缓存都包含一个不同版本的请求文档.可能的值包括 none.星号 (*) 以及任何有效的查询字

ASP.NET数据缓存之数据缓存浅谈

ASP.NET数据缓存的学习是如何呢?如何使用ASP.NET数据缓存呢?在讲ASP.NET数据缓存之前还要先说一下如果在页面中使用参数缓存.前面讲过一个缓存设置VaryByParam="none"为无参数,我们也可以对VaryByParam进行设置,设置的参数与随 GET 方法属性发送的查询字符串值对应,或与使用 POST 方法发送的参数对应.将该属性设置为多个参数时,对于每个指定参数组合,输出缓存都包含一个不同版本的请求文档.可能的值包括 none.星号 (*) 以及任何有效的查询字

ASP.NET2.0缓存(Cache)技术深入理解_实用技巧

ASP.NET2.0提供了一些新的用于提升程序性能的技术特性,其中,缓存技术是非常重要的一个特性,它提供了一种非常好的本地数据缓存机制,从而有效的提高数据访问的性能. 数据缓存(DataCaching)就是将数据暂存于内存缓存区中(有时也暂存于硬盘缓存区中)的一种技术.当数据本身改变得不怎么频繁,而被访问的频率又比较高时,采用这种技术将大大提高警惕数据访问的效率. 1.网页输出缓存 (1)加显缓存 <%@OutputCacheDuration="60"VaryByParam=no

ASP.NET 数据库缓存依赖

asp.net|缓存|数据|数据库 ASP.NET 数据库缓存依赖 By Peter A. Bromberg, Ph.D. 在ASP.NET中,Cache类最酷的特点是它能根据各种依赖来良好的控制自己的行为.以文件为基础的依赖是最有用的,文件依赖项是通过使用 Cache.Insert 并提供引用文件的 CacheDependency 对象添加的 Cache.Insert("MyData", Source, new CacheDependency(Server.MapPath("

ASP.NET的缓存技术

asp.net|缓存 介绍大量的网站页面是采用动态的方式,根据用户提交的不同请求创建生成页面.正如我们所知的,动态页面有助于根据用户要求来提供定制的动态内容.动态页面也利于获取在数据库中每时每刻更新的资料.缺点是为每个用户请求生成同一页面增加了系统开销. 为克服此问题,一些网站用页面生成引擎对所有页面生成html静态页面.但这样生成的页面对所有用户的请求内容都是相同. ASP.NET 提供了缓存技术有助于我们最大程度地解决这个问题.它能缓存输出的页面,保存在存储器当中,缓存用户请求的内容.缓存的