存储session状态在SQL 服务器的数据库中Storing Session State in a SQL Server Database)

Storing Session State in a SQL Server Database
Go to page: 1  2  3  Next  
http://www.developer.com/net/asp/article.php/3595766
 
HTTP 是一种无状态的协议。可以允许用户通过需求来保存状态信息。 ASP.NET 提供了 session 的存储。 Session 变量在基于每用户的原理上被保存的。在经典的 ASP 中,你只能把你的 session 的变量保存在 WEB 服务器的内存之中。然而,在 ASP.NET 2.0 中,你可以把 session 状态保存作为你的每次的需求一样来定制。这篇文章将探究可升级的,可靠的 session 保存途径的一种―― SQL Server
Session 状态跟相关的问题
 
在经典的 ASP 中,通过默认得 session 状态被维持在 WEB 服务器的内存中,然后,这样的做法有两个问题:
  • 加重服务器负担,影响WEB站的可升级性
  • 不能在Web farm场景中有效的使用
Session 变量在每用户的原则上被创建。默认情况下,他们被维护在 WEB 服务器的内存中。想象一下,一个网站有上千个(同时在线)用户。在 WEB 服务器中激活的 Sessions 数量将是非常之大。这意味着你正在储存太多的数据在 WEB 服务器的内存中。如果服务器的负载持续上涨,服务器的负载将达到饱和,然后会给你的应用程序的所有的拓展升级带来麻烦。
为了处理大家所提到的可拓展升级性的问题,(更好的)实现 WEB FARM (技术)。一个 WEB FARM 就是一个并联平行的服务器群。 在这个群中的每台 WEB 服务器有你的网站的映射。你的网站的通信平等的分布在这些可用的服务器中,因而实现了负载的平等分配。保存 session 变量在 WEB 服务器中可能会牵制 WEB FARM 的架构。假设这里有 3 WEB 服务器- S1 S2 ,和 S3 -平行的相连和对进来的请求进行服务。一个请求 R1 进来了这个群,负载平衡的架构逻辑决定了当 S2,S3 繁忙, S1 空闲,可以去处理你的请求的时候。自然的,这个请求被前置到 S1 中去处理。现在,想象一下在处理的过程中,你保存了一个 session 变量在 S1 的内存中,到目前为止,都还好。过了一些时候,同一个用户给了另外的一个请求 R2, R2 需要被 R1 保存的那个 session 变量。然而,这次 S1 在处理另外的一些工作,而 S2 S3 空闲。你可能会希望像前面的负载平衡逻辑规则那样, R2 应该前置到 S2 或者 S3 (去处理)。可是,如果那样做的话, R2 怎么去取访问存在 WEB 服务器 S1 中的 session 变量呢 , 毕竟,他们是保存在完全不同的服务器 S1 上。这就意味着 R2 需要一直等待 S1 变得空闲事,才能够被处理。这就是,显然的, WEB FARM 资源的不合理使用了。
 
ASP.NET 2.0 and Session Storage
ASP.NET 2.0 Session 存储
ASP.NET 2.0 allows you to store session variables at three distinct locations:
ASP.NET 2.0 允许你保存 session 变量在 3 个不同的地方
 
  1. WEB服务器的内存中(在处理过程中)
  2. 在专用的保存sesseion变量的机器中(状态服务器)
  3. SQL 服务器的数据库中
 
第一个模式是默认得。第二和第三模式经常称为“ out-of-process ”模式。因为 session 存储是独立于网站的。在本文中,所有的讨论都将限制在第三种模式。
 
保存 session 变量在 SQL 服务器中有以下的优点:
 
  • 可拓展性:如果你正在找一个高度可升级的选择来保存你的session变量的话,SQL服务器是一个选择。它比其它的选择更具有拓展升级的性能。Web farm 架构能够非常容易的访问session 变量因为它们存储在一个独立的数据库中。
  • 稳定性: 因为数据在数据库中是物理的持续的,这比其它任何一种都要稳定。即使服务器重启了,数据都还完好。
  • 安全性:SQL Server 比任何的内存中保存session或者专用的状态服务器选择都要来得安全。你可以很容易的通过配置SQL 服务器的安全设置来保护你的数据安全。
 
 
Session 状态模式可以通过 web.config 文件的 <sessionState> 标记被配置 .
 
注意 :
·   Web farm 场景中 , 所有的 WEBFARM 中的服务器的 IIS metabase 网站程序路径应该是同一路径
·   Session_End 事件不能因为任何异常模式而被使用
配置 SQL 服务器来存储 Session 状态
在你存储 session 状态在 SQL 服务器之前 , 你需要去配置它 . 这些配置可以通过一个叫 ASPNET_REGSQL.EXE 的命令行工具来实现 . 你可以存储 session 状态在三个可能的地点 . 这些地点都是在 SQL 服务器之内的 .
 
  • 临时存储: 在这种情况下, session 状态被存储在一个"临时数据库"SQL 服务器的数据库中. 这个工具创建了一个叫ASPState的数据库, 还添加了一些管理session的存储过程在里面. 这个工具还创建必需的表在临时数据库. 如果你重启了SQL 服务器,这些session数据将被删除.  
  • 持久存储: 这个工具创建了一个叫ASPState 的数据库, 还添加了一些管理session的存储过程在里面. Session 状态被储存在ASPState的数据库中.
 
  • 定制存储: session 和存储过程都被存储在一个定制的数据库中. 这个数据库的名字必须在配置文件中被指定.
 
 
 
以下的表列出了有关于 session 存储配置工具转换的不同命令 :
 
Command line switch
Description
-S <server>
指定你想要用于存储 session 状态的数据库的 IP 地址或者名字
-U
指定被用来连接数据库的用户 ID
-P
指定被用来连接数据库的密码
-E
指出你想要连接的服务器需要完整的安全策略
-ssadd
添加支持服务器模式的 session 状态
-ssremove
移除支持服务器模式的 session 状态
-sstype
Session 状态支持的类型 , 一下是可以支持的类型 :
t 代表临时存储
p
代表持久存储
c
代表定制储存
-d <database>
用于使用的数据库的名字 如果要转换 - sstype, 就用命令 ”c”
Tables and Stored Procedures Created
表单和创建的存储过程
作为一个开发人员 , 你可能从来无法对 session 状态数据库进行直接的影响 . 然而 , 当你运行 ASPNET_REGSQL.EXE 工具 , 你将会对表单跟数据库的创建会有一个很好的理解 .
 
Figure 1: SQL 数据库服务器中创建表单
Figure 2: 在数据库服务器中创建存储过程
 

配置你的网站来存储Session 状态

一旦你配置你的SQL服务器来支持session状态存储,下一步就是配置你的网站了。web.config 的标记<sessionState>允许你指定session存储的信息。下列的表中列出了一些这个标记得重要属性:

属性

描述

mode

Mode属性可以使用一下的几个值:

Off:指示这个session状态关闭.
InProc:
指示这个session 将被存储在web服务器的内存中。这是默认的设置                                   StateServer:指示这个session将被储存在一个状态服务器中 SQLServer: 指示这个session将被储存在一个SQL服务器的数据库中.
Custom:
指示你将会有一个定制的session存储机制,这个机制使用了ASP.NET的提供的模式

sqlConnectionString

如果模式被设置为SQL服务器,你必须指定这个属性。这个属性指定了那个SQL服务器数据库的连接字符串。这个数据库的是用来进行状态的存储的。注意,如果你使用了临时的或者持久的存储选项时候,你不需要在连接字符串中指定数据库的名称(见上)

 

allowCustomSqlDatabase

如果你想去存储session状态在一个你自己的SQL服务器的数据库中的时候,你必须设置这个属性为“TRUE”。一旦这个属性被设置为true,你要在上面说描述的连接字符串中指定数据库的名称。

例子   

你可以开发一个简单的网站,设置它来存储一个sesseion状态在一个SQL服务器的数据库中,来示例你到目前为止以上所学的。

设置SQL服务器

打开Visual Studio.NET 2005命令提示器,使用一下命令

aspnet_regsql -ssadd -S .sqlexpress -E -sstype p

 

aspnet_regsql -ssadd -S .sqlexpress -E -sstype p

 

这里,你正在使用SQL Express 作为带着完整安全的数据库

Figure 3 展示了一个把带着session 状态类型的工具设置为"persistent"的例子。




Click here for a larger image.

Figure 3: 运行ASPNET_REGSQL.EXE工具    

创建和配置一个网站

现在,创建一个新的网站,修改web.config文件成下列的代码

<sessionState

mode="SQLServer"

sqlConnectionString="data source=.sqlexpress;

integrated security=true">

</sessionState>

这里,你添加了这个<sessionState>标记,设置它的模式属性为SQLServer。你还要指定sqlConnectionString属性,把它指向你的SQL SERVER

创建测试网站的WEB窗体

 

WEB站点中添加两个WEB窗体。这两个窗体分别叫page1.aspxpage2.aspx。第一个WEB窗体将显示一个产品列表来选择。被选择的产品被保存在一个DataSet中。然后通过保存这个DataSet 在一个session变量中来把它在请求中传递。第二个Web窗体简单的显示了来自DataSet中的被选择的产品。

通过一下的步骤来完成第一个Web 窗体:

  1. 拖拉一个GRIDVIEW控件和一个SQL Data Source控件在WEB FORM.
  2. 配置SQL Data Source, Northwind 数据库的Products 表中选择ProductID, ProductName, UnitPrice columns
  3. 通过设置他的DataSourceID属性到SQL Data Source控件的ID属性上来绑定GridViewSQL Data Source.
  4. GridViewsamrt标记上, 点击"Allow Selection" checkbox.
  5. 添加一个HyperLink 控件,设置NavigateUrl属性到Page2.aspx.

下列的标记是由上面的操作生成的(出去不必要的代码)

...

<asp:GridView ID="GridView1" runat="server"

              AllowPaging="True" AutoGenerateColumns="False"

              CellPadding="4" DataSourceID="SqlDataSource1"

              ForeColor="#333333" GridLines="None"

              Width="100%"

              OnSelectedIndexChanged="GridView1_SelectedIndexChanged"

              PageSize="5">

   <FooterStyle BackColor="#990000" Font-Bold="True"

                ForeColor="White" />

   <Columns>

      <asp:BoundField DataField="ProductName"

                      HeaderText="ProductName"

                      SortExpression="ProductName" />

      <asp:BoundField DataField="UnitPrice"

                      HeaderText="UnitPrice"

                      SortExpression="UnitPrice" />

      <asp:CommandField SelectText="Add to cart"

                        ShowSelectButton="True" />

   </Columns>

</asp:GridView>

...

<asp:HyperLink ID="HyperLink1" runat="server"

               NavigateUrl="~/Page2.aspx" Font-Bold="True"

               Font-Size="Large">Show my cart</asp:HyperLink>

...

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

                   ConnectionString=

                   "<%$ ConnectionStrings:NorthwindConnectionString %>"

                   SelectCommand="SELECT [ProductName],

                   [UnitPrice] FROM [Products]

                   ORDER BY [ProductName]"></asp:SqlDataSource>

Now, add the following code to the SelectedIndexChanged event of the GridView:

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)

{

   DataSet ds=null;

   if (Session["myds"] == null)

   {

      ds = new DataSet();

      DataTable dt = new DataTable();

      dt.Columns.Add(new DataColumn("ProductName"));

      dt.Columns.Add(new DataColumn("Qty", typeof(System.Int32)));

      ds.Tables.Add(dt);

      Session["myds"] = ds;

   }

   else

   {

      ds = (DataSet)Session["myds"];

   }

   DataRow row=ds.Tables[0].NewRow();

   row["productname"]=GridView1.Rows[GridView1.SelectedIndex].

      Cells[0].Text;

   row["Qty"]=1;

   ds.Tables[0].Rows.Add(row);

}

这里,你可以创建一个 DataSet   DataTable. FataTable 包含两个DataColumns: ProducyName Qty. 然后你存储一个session变量"myds".当用户选择一个产品的时候, 你可以创建一个新的DataRow, 分配产品的资料给它, 添加这个ROWDataTable. 用户的选择可以在跨多个请求中持续.

按一下的步骤创建第二张的Web form

  1. 拖拉一个GridViewWeb form.
  2. 添加两个绑定区域
  3. 设置第一个绑定区域的HeaderText属性成"Product Name". 同样的,设置DataField"Product Name".
  4. 设置第二个绑定区域的HeaderText属性成"Quantity". 同样的,设置DataField" Qty ".

 

下列的标记是由上面的操作生成的(除去不必要的代码)

 

 

...

<asp:GridView ID="GridView1" runat="server"

              AutoGenerateColumns="False" CellPadding="4"

              ForeColor="#333333" GridLines="None" Width="100%">

   <FooterStyle BackColor="#1C5E55" Font-Bold="True"

                ForeColor="White" />

   <Columns>

      <asp:BoundField DataField="productname"

                      HeaderText="Product Name" />

      <asp:BoundField DataField="qty"

                      HeaderText="Quantity" />

   </Columns>

</asp:GridView>

...

添加下列的代码到第二张Web Form Page_Load event handler

protected void Page_Load(object sender, EventArgs e)

{

   GridView1.DataSource=(DataSet)Session["myds"];

   GridView1.DataBind();

}

 

这里,你设置GridView控件的DataSource属性到你的储存在session上的DATASET.

然后你通过调用DataBind() 方法来绑定GridView.

运行WEB FORMS 的例子

为了测试你的WEB FORMS, 设置Page.aspx 作为你的起始页, 然后运行你的WEB SITE. 你应该看到如图4所展示的:

Figure 4: 运行Page1.aspx 的例子

 

 

通过”Add to cart”按钮选择一些产品. 这将会添加一些行在DataTable. 记得你正在存储你的DataSet在一个session变量之中. 然后,通过点击”Show my cart” 超链接导航到 Page.aspx . 5显示了带着前面所选的产品的Page.aspx.

Figure 5: Sample run of Page2.aspx

正如你所见的, Page2.aspx 正确的显示了你在前页所选的那些条目. 这显示了你的session 变量被真正的存储在了SQL服务器的数据库中,并被在第二页中找回. 还有, 注意你在无关储存模式的session中用了相同的存储调用值得标记.

储存Session状态在SQL服务器中的劣势

虽然存储session状态在SQL 服务器中可以使你的网站更容易拓展和更稳定. 但是这个技术有一下的几个劣势

 

  • 执行上: 在执行的几个项目中,一个基于SQL SERVERsession 存储可能是一个最慢地选择. 因为你的session变量是存储在物理的数据库中.它用了更多的时候去存储和读取数据库. 这会影响了你的网站的运行速度.
  • 花费: 因为你存储你的数据在数据库中, 你需要一个SQL数据库的执照, 这将给你的网站带来额外的开销.
  • 连续的数据: 这个方法要求你所有保存在session变量中的数据必须是连续的. 如果你想存储数据在一个session,这也许强制你去标记你自己的类作为[Serializable].

总结

rage options.

ASP.NET 2.0 可以允许你存储session状态到一个SQL服务器的数据库. ASPNET_REGSQL.EXE工具配置了数据库来支持这个特性. 更进一步, <sessionState>标记配置你的网站来支持这个模式. 存储一个session状态在一个SQL服务器中是一种更具拓展,安全性和稳定性的选择. 然后, 这种选择的运行相对于其他选择而言将会更慢.

下载代码,

You can download the code that accompanies the article here.

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值