分享
 
 
 

在 ASP.NET 中支持数据库缓存相关性

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

开发人员都喜欢 ASP.NET 应用程序缓存。 一个原因是 ASP.NET 能够在放入缓存中的项与文件系统中的文件之间创建相关性。 如果相关性所针对的文件更改,ASP.NET 会自动将相关项从缓存中删除。 通过与缓存删除回叫(当缓存项删除时向所有关注方广播通知)结合,缓存相关性为开发人员提供了方便,使他们得以通过尽量减少耗时的文件访问来最大限度地提高性能,因为这使他们可以放心地允许文件数据缓存,而不必担心数据变得陈旧。

尽管缓存相关性非常实用,但是在 ASP.NET 1.0 中还缺乏一项至关重要的功能,这项功能一旦存在,将会使缓存相关性随着开发人员的美梦成真而得到证明。 这项功能就是对数据库实体的支持。 在现实情况中,大多数 Web 应用程序都是从数据库中提取数据,而不是从文件中提取数据。 尽管 ASP.NET 能够非常出色地将缓存项链接到文件,但无法将缓存项链接到数据库实体。 也就是说,可以将文件内容读入 DataSet 中,然后缓存 DataSet,并使 DataSet 在初始化时所在的文件更改时自动从缓存中删除。 但是,无法使用数据库查询来初始化 DataSet,因此也就无法缓存 DataSet 并使 DataSet 自动在数据库更改时废弃。 这确实太糟糕了,因为正是由于数据库访问过多(例如,文件 I/O 过多)而导致应用程序性能下降。

ASP.NET 不支持数据库相关性并不意味着数据库相关性不可能实现。 这一部分 Wicked Code 展示了扩展 ASP.NET 应用程序缓存以支持数据库相关性的技术。 它包含数据库触发器及扩展存储过程。 尽管这里展示的实现仅适用于 Microsoft? SQL Server?,但是大体技术也适用于支持与文件系统交互的触发器和用户定义过程的任何数据库。

活动的数据库相关性

先看一个演示。

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClient" %>

<html>

<body>

<h3><asp:Label ID="Quotation" RunAt="server" /></h3>

<i><asp:Label ID="Author" RunAt="server" /></i>

</body>

</html>

<script language="C#" runat="server">

void Page_Load (Object sender, EventArgs e)

{

SqlDataAdapter adapter = new SqlDataAdapter (

"SELECT * FROM Quotations",

"server=localhost;database=quotes;uid=sa;pwd="

);

DataSet ds = new DataSet ();

adapter.Fill (ds, "Quotations");

DataTable table = ds.Tables["Quotations"];

Random rand = new Random ();

int index = rand.Next (0, table.Rows.Count);

DataRow row = table.Rows[index];

Quotation.Text = (string) row["Quotation"];

Author.Text = (string) row["Author"];

}

</script>

上面代码包含 ASP.NET 页的源代码,该 ASP.NET 页显示从名为 Quotes 的 SQL Server 数据库中随机选择的语录。 要创建数据库,请运行安装脚本。

CREATE DATABASE Quotes

GO

USE Quotes

GO

CREATE TABLE Quotations (

Quotation varchar(256) NOT NULL,

Author varchar(64) NOT NULL

)

GO

INSERT INTO Quotations (Quotation, Author) VALUES (

'Give me chastity and continence, but not yet.',

'Saint Augustine'

)

•••

INSERT INTO Quotations (Quotation, Author) VALUES (

'640K ought to be enough for anybody.',

'William Gates III'

)

GO

上面代码显示的是缩略形式的安装脚本。 完整的脚本包含在本专栏附带的可下载 zip 文件中。 (可以在 SQL Server 查询分析器内部执行该脚本,或者使用 OSQL 命令从命令行执行该脚本。) 每次提取该页时,Page_Load 都使用数据库的 Quotations 表中的所有记录初始化一个 DataSet,然后从该 DataSet 中随机选择一个记录,并将其写入到该页中。 按 F5 若干次,您将看到出自某些著名(以及不那么有名的)人士的各种随机语录,如图 3 所示。

图 3 随机语录

由于某一原因,该页被命名为 DumbDBQuotes.aspx。 每次请求该页时都查询数据库并不是很明智的做法。 在每一次访问该页时都访问数据库(尤其是当数据库是由远程服务器承载时)是生成不具可伸缩性的数据库的可靠方法。

ASP.NET 应用程序缓存可解决数据库访问过多的问题。 如果 DataSet 已缓存,便可以直接从内存(也就是缓存)中提取它,从而避免了多余的数据库访问。 DataSet 的缓存非常容易。应用程序缓存接受从 System.Object 派生的任何类型的实例。在 Microsoft .NET Framework 中,这意味着任何托管类型(包括 DataSet)的实例。 问题在于,如果在 DataSet 缓存之后,它底层的数据库更改,您为用户提供的将是陈旧的数据。 可以实现一个定期重新查询数据库的解决方案,但是理想的解决方案应该满足以下条件:不需要轮询,并且在数据源中的已更新数据一旦变得可用时便立即将其交付。

请看

<%@ Import NameSpace="System.Data" %>

<%@ Import NameSpace="System.Data.SqlClient" %>

<script language="C#" runat="server">

static Cache _cache = null;

void Application_Start ()

{

_cache = Context.Cache; // Save reference for later

//

// Query the database and cache the resulting DataSet.

//

RefreshCache (null, null, 0);

}

static void RefreshCache (string key, object item,

CacheItemRemovedReason reason)

{

//

// Query the database.

//

SqlDataAdapter adapter = new SqlDataAdapter (

"SELECT * FROM Quotations",

"server=localhost;database=quotes;uid=sa;pwd="

);

DataSet ds = new DataSet ();

adapter.Fill (ds, "Quotations");

//

// Add the DataSet to the application cache.

//

_cache.Insert (

"Quotes",

ds,

new CacheDependency ("C:\\AspNetSql\\Quotes.Quotations"),

Cache.NoAbsoluteExpiration,

Cache.NoSlidingExpiration,

CacheItemPriority.Default,

new CacheItemRemovedCallback (RefreshCache)

);

}

</script>

<%@ Import Namespace="System.Data" %>

<html>

<body>

<h3><asp:Label ID="Quotation" RunAt="server" /></h3>

<i><asp:Label ID="Author" RunAt="server" /></i>

</body>

</html>

<script language="C#" runat="server">

void Page_Load (Object sender, EventArgs e)

{

DataSet ds = (DataSet) Cache["Quotes"];

if (ds != null) {

// Display a randomly selected quotation

DataTable table = ds.Tables["Quotations"];

Random rand = new Random ();

int index = rand.Next (0, table.Rows.Count);

DataRow row = table.Rows[index];

Quotation.Text = (string) row["Quotation"];

Author.Text = (string) row["Author"];

}

else {

// If quotes is null, this request arrived after the

// DataSet was removed from the cache and before a new

// DataSet was inserted. Tell the user the server is

// busy; a page refresh should solve the problem.

Quotation.Text = "Server busy";

}

}

</script>

这两个图中包含更智能的语录应用程序的源代码。 SmartDBQuotes.aspx 不从数据库中检索语录,而是从应用程序缓存中获取语录。 Global.asax 填充缓存,并在数据库更改时刷新缓存。

下面是这两段源代码的试用说明:

• 在 Web 服务器的 C: 驱动器的根目录中创建一个名为 AspNetSql 的子目录。 在 AspNetSql 内部,创建一个名为 Quotes.Quotations 的零字节文件。 确保 Everyone,或者至少 SYSTEM 和 ASPNET(安装 ASP.NET 时创建的特殊帐户)有权访问 Quotes.Quotations。

• 将包含在本专栏的可下载代码示例中的 XSP.dll 复制到 SQL Server 的 binn 目录(例如,C:\Program Files\Microsoft SQL Server\MSSQL\Binn)中,或者复制到 Web 服务器上 Windows 将在其中自动搜索 DLL 的任意位置(例如,C:\Windows\System32)。

USE master

EXEC sp_addextendedproc 'xsp_UpdateSignalFile', 'XSP.dll'

GRANT EXECUTE ON xsp_UpdateSignalFile TO PUBLIC

GO

CREATE DATABASE Quotes

GO

USE Quotes

GO

CREATE TABLE Quotations (

Quotation varchar(256) NOT NULL,

Author varchar(64) NOT NULL

)

GO

INSERT INTO Quotations (Quotati

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有