DataSource Control 之Cache机制
原文地址:http://blog.csdn.net/Code6421/archive/2008/01/03/2012314.aspx
文/黄忠成
将常用的数据对象放到Cache中,可以有效的提升整个网站的执行效能,当使用DataSource Control时,只要将EnableCacheing属性设为True,此DataSource Control在数据选取后,便会将数据对象放到Cache中,视乎Cache过期条件的设定,在数据对象未过期前,接下来同样条件的选取数据动作,便是直接从Cache中取出,而不需再至数据库中选取数据。目前ASP.NET 2.0中内建的DataSource Control,除了SiteMapDataSource外,其它至少都支持两种Cache条件设定,一是时间制,将数据对象是否过期的工作交由系统来控制,另一种是CacheDependency制,由CacheDependency对象来控制数据对象何时该过期,表4-5-2列出这两种机制的设定方式及说明。
表4-5-2
|
过期条件 |
说明 |
|
时间制 |
当CacheExpirationPolicy属性为Absolute时,透过设定CacheDuration属性值来决定Cache的过期时间,该属性值是以秒为单位,30代表当数据对象放到Cache中后,30秒后即会由Cache中移除,之后的选取数据动作将重新由数据库中取出数据再放入Cache中。当CacheExpirationPolicy属性为Sliding时,CacheDuration属性代表着当数据对象放到Cache中后,经过多少时间无人存取,即从Cache中移除,例如将CacheDuration设为30,代表着30秒内无人存取时,数据对象即由Cache中移除,若有人存取,则将时间归零,重新计算。 |
|
CacheDependency制 |
使用CacheDependency对象的方式来决定是否过期,设计师必须先放入一个CacheDependency对象至Cache中,再将其Key值设定给SqlDataSource控件的CacheKeyDependency属性值,当SqlDataSource控件选取数据后,将数据对象放入Cache时会以此CacheDependency为过期条件,也就是说当此CacheDependency被移除、或是值被改变时,就视同数据对象已经过期。 |
时间制的特色是全权交由系统来控制,设计师并无从得知数据对象何时过期,也无法手动控制,所以大多用于不常更新、且没有数据不同步问题的数据对象,程序4-5-4是一个使用时间制的范例,该程序放入了一个SqlDataSource控件、一个DropDownList控件及一个Button控件,SqlDataSource控件连结至Northwind数据库的Customers数据表,并将EnableCaching设为True、CacheExpirationPolicy设为Absolute、CacheDuration设为60。DropDownList控件的DataSourceID为SqlDataSource1、DataTextField及DataValueField皆为CustomerID。
程序4-5-4
|
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page { //SqlDataSource1 //SQL = SELECT * FROM Customers //CacheExpirationPolicy = Absolute //CacheDuration = 60 //EnableCaching = True //------------------------------------ //DropDownList1 //DataSourceID = SqlDataSource1 //DataTextField = CustomerID //DataValueField = CustomerID //------------------------------------ //Button1 protected void Page_Load(object sender, EventArgs e) { }
protected void Button1_Click(object sender, EventArgs e) { DropDownList1.DataBind(); } } |
此程序第一次执行时,SqlDataSource控件会由数据库将数据取出后放到Cache中,之后按下Button1会触发Click事件,此处重新呼叫了DropDownList控件的DataBind函式,迫使DropDownList控件重新对SqlDataSource控件要求数据,此时SqlDataSource控件便会从Cache中取出数据传回,不再向数据库索取数据。待设定的60秒过后,Cache中的数据对象将会被移除,此时再对SqlDataSource控件要求数据的话,就会重新由数据库选取数据再放入Cache中。那我们该如何确认Cache机制是否正常运作了呢?很简单,只要挂载事件到SqlDataSource控件的Selecting后,于其中下断点即可,当数据是由Cache取出时,Selecting事件不会被触发,反之则会触发。另一种Cache机制是以时间制为基础,再搭配CacheDependency对象来管理Cache的过期时间,这种机制比单纯使用时间制更为灵活,设计师可以在数据对象更新时,以程序的方式来迫使Cache的数据对象过期,程序4-5-5是一个使用CacheDependency对象的范例。
程序4-5-5
|
protected void Page_Load(object sender, EventArgs e) { Label1.Text = "Data is from Cache"; if (!IsPostBack) { if (Cache["CustomersTable"] == null) { Cache["CustomersTable"] = new CacheDependency(new string[0] {}); } } } protected void Button1_Click(object sender, EventArgs e) { Cache.Remove("CustomersTable"); DropDownList1.DataBind(); } protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e) { Label1.Text = "Data is from Database"; } |
这个范例中放入一个SqlDataSource控件、一个Button、一个Label,SqlDataSource控件连结至Northwind的Customers资料表,EnableCaching为True,CacheDuration为50,CacheExpirationPolicy为Absolute,CacheDependencyKey属性设为CustomersTable。DropDownList控件连结至SqlDataSource控件,DataTextField与DataValueField皆为CustomerID。此程序一开始的Page_Load函式时,先判断是否处于PostBack模式,只有在非PostBack模式时,此范例才有执行DataBind的需求,此处先行判断CustoemrsTable是否已经存在Cache中,是的话就代表数据对象已经在Cache中了,否的话就于Cache中插入CustomersTable,接下来的DataBind动作会是由数据库中选取数据,然后以CustomersTable作为CacheDependency来管理数据是否过期,当IsPostBack为False,而Cache中已有CustomersTable存在时,对SqlDataSource控件要求的数据将来自于Cache,当然!前题是CacheDuration所设定的时间还没到。接下来的Button控件处理了Click事件,于此将Cache中的CustomersTable移除,然后呼叫DropDownList控件的DataBind函式,由于CacheDependency已经被移除了,此处的DataBind函式将会迫使SqlDataSource控件由数据库中取得数据,此时便会触发SqlDataSource控件的Selecting事件,于此改变Label控件的Text属性值。执行此网页后,第一次将会看到Label显示数据来自数据库,当重新刷新网页时(不是按Button哦,是IE的重新整理),会看到资料已来自Cache,此后的50秒内不管刷新网页几次,资料都是来自于Cache,待50秒过后、或是按下网页上的Button后,数据才会重新由数据库中取出。
图4-5-27(第一次启动网页、或按下Button后)
图4-5-28(于50秒内重新刷新页面时)
运用CacheDependency对象来控制数据对象的过期,对设计师来说是常用的手法。
SqlDependency
SqlDataSource、AccessDataSource、ObjectDataSource都支持另一个Cache机制:SqlDependency,此机制会侦测指定的数据库中的数据表是否变动,若变动时数据对象会自动过期,原本这是属于SQL Server 2005才有的新功能,经由ASP.NET 2.0的开发团队的努力,现在此功能已经能运用在SQL Server 7以上版本的数据库中了。SqlDependency看似神奇,但其实原理很简单,就是利用数据库的 Trigger机制,当数据表有所变动时,会触发设定的Trigger,而ASP.NET 2.0所做的不过是在数据库中产生此Trigger,并将变动存放至指定的数据表中,而SqlDependency则定期的去检视这个资料表,一发现有所变动后就将数据对象标示为过期。由以上的叙述可以得知几个使用SqlDependency前所需的条件,一、数据库必须建立用来储存变动信息的数据表,二、数据表必须挂载侦测变动的Trigger,这两个步骤都可透过aspnet_regsql.exe来完成,请开启Visual Studio 2005 Command Prompt窗口,然后键入如图4-5-29的命令。
图4-5-29
第一个命令是建立储存变动信息的数据表,此处-S后面接的是SQL Server的名称、-U接的是登入时的使用者名称、-d接的是要建立数据表的数据库、-ed代表于此建立储存变动信息的数据表。第二个命令是建立侦测变动的Trigger,-et代表欲建立侦测变动的Trigger,-t后面接着是要侦测的数据表名称,完成后可以于SQL Server中看到如图4-5-30的画面。
图4-5-30
在使用SqlDependency之前,得在web.config中添加程序4-5-6的设定,告知要侦测的数据库及联机字符串、侦测的时间周期。
程序4-5-6
|
<?xml version="1.0"?> <configuration> <appSettings/> <connectionStrings> <add name="NorthwindConnectionString" connectionString="Data Source=JEFFRAY"SQL2005;Initial Catalog=Northwind;User ID=sa" providerName="System.Data.SqlClient"/> </connectionStrings> <system.web> <caching> <sqlCacheDependency enabled="true"> <databases> <add name="Northwind" connectionStringName="NorthwindConnectionString" pollTime="12000" /> </databases> </sqlCacheDependency> </caching> |
请注意databases区段的add Tag中的信息,name代表要侦测的数据库别名,这待会要设定在DataSource Control的SqlDependency中,connectionStringName参考至上方的connectionStrings区段中的设定,此处是以NorthwindConnectionString的联机字符串来连结至SQL Server,然后以pollTime:12000,也就是每12秒侦测一次来决定数据对象是否过期。设定完毕后,便可建立一个新网页,如同前例般放入Button、SqlDataSource、Label、DropDownList等控件并照前例的方式设定她们(不要设定CacheKeyDependency属性,将CacheDuration设为300、CacheExpirationPolicy设为Absolute),此处请设定SqlDataSource控件的SqlDependency为Northwind:Customers,这个字符串代表着侦测Northwind数据库(对应web.config中databases中的name)中的Customers数据表的变动,来决定数据对象是否过期,当欲侦测多个数据表时,可采;分格,例如:Northwind:Customers;Northwind:Employees、当需侦测不同数据库的不同数据表时,也是同样的方式:Northwind:Customers;AdvanceNorthwind:Employees。程序4-5-7为使用SqlDependency的范例。
程序4-5-7
|
public partial class UsingSqlDependency : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Label1.Text = "Data is From Cache"; } protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e) { Label1.Text = "Data is From Database"; } } |
当第一次执行时,网页会显示数据来自数据库,当第二次执行时,若CacheDuration所设的时间未过期,那么将显示数据来自Cache,当资料表有所变动时,视修改的时间而定,最慢在12秒后刷新网页将会得到数据来自于数据库的讯息。
再论Cache
前面已经谈过DataSource Control的Cache机制及SqlDataSource的编辑数据能力,现在读者们心中应会升起两个疑问,第一个是DataSource Control的Cache视界问题,当一个网站中有两个网页,每个网页中都有一个SqlDataSource控件,用同样的SQL指令至同一个数据库中选取数据,而Cache已经启用,此时 Cache中会有一份数据对象还是两份呢?答案是一份,因为DataSource Control会依据联机字符串、SQL指令来运算出一个键值,再用这个键值将数据对象存入Cache中,同样的联机字符串及SQL指令所运算出的键值是相同的。第二个问题是,当对DataSource Control下达更新动作,如Insert、Update等等,此时Cache中的数据对象必须移除,重新选取最新的数据,而这个动作是要设计师去做,还是DataSource Control?答案是DataSource Control,当Insert、Udpate等函式被呼叫时,DataSource Control便会移除Cache中的数据对象,当下次Select被呼叫时,就会重新由数据库中选取数据。
浙公网安备 33010602011771号