中国站长下载-为中国站长提供最好最全的建站资源! 首 页发布资源有事留言繁體中文
设为首页
加入收藏
联系我们
 
您当前的位置:中国站长下载 -> 文章中心 -> 网页编程 -> .NET编程 -> 文章内容  虚拟主机 域名注册 退出登录 用户管理
栏目导航
· ASP编程 · .NET编程
· PHP编程 · JSP编程
· CGI 专区
热门文章
· sndvol32 - sndvol3...
· [组图] FLASH:《大话李白》...
· 个人网站到底能赚多...
· [图文] Rundll.exe是病毒吗...
· [组图] Flash:制作MV
· 价值12万元的网站SE...
· 网站创业者,你需要...
· 一个成功的网站设计...
· [图文] FLASH:韩国导航条解...
· 中国网站的赚钱模式...
相关文章
· [图文] 用ASP.NET 2.0设计网...
· [图文] 用ASP.NET 2.0设计网...
· [图文] 用ASP.NET 2.0设计网...
· [图文] 用ASP.NET 2.0设计网...
· [图文] 用ASP.NET 2.0设计网...
· ASP.NET中WebForm组...
· ASP.NET中WebForm组...
· ASP.NET中WebForm组...
· ASP.NET中WebForm组...
· ASP.NET计数器
ASP.NET应用中缓存Oracle数据(2)
作者:不详  来源:不详  发布时间:2006-8-14 9:23:18  发布人:chinazhan

 减小字体 增大字体

     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部署。
    做人要厚道,请注明转自chinazhan中国站长(www.ChinaZhan.com)。

 
[] [返回上一页] [打 印] [收 藏]
∷相关文章评论∷    (评论内容只代表网友观点,与本站立场无关!) [更多评论...]
中国站长下载
中国站长下载

本页只接受PR>=4 IT类站点连接,申请连接,谢谢您们的支持!希望我们的下载站能够真正帮到中国的站长们!
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图
Copyright © 2005-2006 ChinaZhan.Net. All Rights Reserved .