【问题标题】:Struggling with acceptable use of Session variable in ASP.NET在 ASP.NET 中努力使用可接受的 Session 变量
【发布时间】:2010-10-24 09:18:27
【问题描述】:
我试图放弃在 ASP.NET 中将所有内容都保存在 Session 变量中(我来自 Windows 编程背景),并且我通常完全停止在 Session 变量中显式存储任何内容。任何人都可以就您认为可接受的会话变量使用提供一些指导吗?
这是一个具体的例子...我从数据库中加载一个业务对象并填充和编辑屏幕。用户可以编辑值并保存。我将加载业务对象、加载表单并将业务对象保存到会话变量的旧方法。如果用户单击保存,我将从会话变量中检索业务对象,替换已编辑的值,然后保存它。我从数据库加载业务对象并加载表单的新方法。用户将编辑这些值并单击保存。我将从数据库中重新加载我的业务对象,替换已编辑的值,然后保存它。我不是网络编程专家,但我觉得第一种方法是错误的,因为使用会话变量的耻辱,我觉得第二种方法是错误的,因为它感觉就像是一种糟糕的方式(加载业务对象两次)。我们在这里不考虑任何形式的缓存。我该如何处理?
【问题讨论】:
标签:
asp.net
session-variables
【解决方案1】:
在回帖时从数据库中重新加载业务对象以保存用户更改,我一点也不生气。
该对象必须来自该回发的某个地方,并且与快速数据库调用(例如抓取特定对象)相关的有限开销可能是您最好的选择。
您在回发时将该业务对象恢复到内存中的选项:
- 再次从数据库中获取它。缺点:一些(小)额外的数据库开销
- 将其保存在用户的会话中。缺点:可能仍在访问数据库(如果会话状态存储在那里)或使用大量内存(如果会话状态存储在那里)并且如果多个用户可能正在访问该对象并且最糟糕的是该会话,则可能会存储多个副本如果 ASP.NET 出于某种原因清除了对象,则用户点击提交后该对象可能会消失。
- 来自缓存。缺点:使用一些额外的内存,如果缓存不存在,你仍然需要去数据库,但我会投入大笔资金,因为任何应用程序都有很多更大的瓶颈来使用缓存。
- 视图状态。您可以将对象存储在 Viewstate 中(将其发送给客户端,然后客户端将其发回)。缺点:在我看来,最糟糕的解决方案。将它添加到 Viewstate 意味着它会通过下游和上游的线路,并导致页面大小很大。 Session 不是最好的,但 Viewstate 是魔鬼。
【解决方案2】:
你有很多用户吗?
如果您的网站容量较小,将您的业务对象存储在会话中可能没问题。
如果您使用 SQL Server 来存储会话,那么您实际上是在每次回帖时都从数据库中加载您的业务对象。
不过,根据经验,我倾向于使用 Session 仅存储适用于用户会话生命周期的信息。特定于单个 Web 表单的业务对象并不真正适合此类别。对于大容量站点,此策略也可能会帮助您更好地扩展。这取决于所有相关因素。
:)
【解决方案3】:
在更新之前从数据库中重新加载对象可能非常危险。您最终可能会错过任何可能的并发冲突。
例如,如果发生此流程:
- 在计算机 1 上显示客户 1 的编辑屏幕
- 在计算机 2 上显示客户 1 的编辑屏幕
- 从计算机 1 处理对客户 1 的更新
- 从计算机 2 处理客户 1 的更新
(4) 可能由于并发冲突而失败,即更新正在覆盖计算机 2 不知道的更改。但是通过从数据库重新加载,您忽略了这些问题并实现了最后一次更新。
因此,对于这种情况,如果您完全关心并发性,我认为将原始实体放在会话中(或表单上的隐藏字段中)绝对是正确的做法。
更不用说很多人不喜欢再次访问数据库以获得额外的阅读...