2010-10-21 62 views
0

我最近的任务是修复由于会话状态被滥用而导致的相当恶劣的错误。我们有一个使用inproc会话状态在单台服务器上运行的asp.net Web应用程序。基本设计是从数据库中加载类型化数据集,并使用常见会话变量名称(如Session [“dataset”] = dataset)存储在会话状态中。数据存储在会话中后,用户将编辑数据,从会话中检索数据集并更新并发送到数据库进行更新。这种类型的数据编辑\存储用于基本上执行相同操作的多个Web表单。直到用户尝试启动应用程序的第二个实例并且会话变量中存储的数据可能混淆为止,这一切都是好事。如何最好地解决InProc会话状态变量多实例问题?

这里是我已经能够找到

  1. 设置的sessionState无Cookie =“假”(每一个新实例都有一个唯一的会话ID) 专业人士那里获得可能的解决方法 - 最简单的方法,几乎​​没有任何代码改变需要 缺点 - 在URL全局唯一标识符,用户可以编辑GUID,GUID可以复制

  2. 使用自定义会话密钥对每个实例(大约传递一个会话密钥,并结合它的“数据集” +会话密钥的名称,以便每个实例都有一个唯一的会话变量) PROS - 没有一个GUID URL 缺点 - 大部分的代码量的变化,可能是脆弱的

  3. 删除会话变量(负载从数据库中的数据集进行编辑第二次) PROS-释放了服务器资源,不再依赖会话状态 缺点 - 性能命中,代码的高量变化

任何人都知道任何其他可能的解决方案?谢谢

回答

0

那么,保证两个实例不会访问同一个sessionstate的唯一方法就是使用url/POST-data做一些事情。这就是你必须玩的。

最简单的可能是使用cookieless = true,并希望所有url:s被正确地重写。最好的办法可能就是直接访问数据库,很可能不会像你想象的那样影响数据库,如果它影响到,你不应该为每个用户缓存大量数据,而应该使用全局缓存。

+0

我同意,缓存每个用户的数据是不好的。这就是我试图解决它的原因。当你说使用“全局缓存”时,我不确定你的意思。我已经为应用程序范围的数据使用了应用程序缓存,但是如何为每个用户加载的数据工作? – NullReference 2010-10-21 21:44:02

+0

全球是相对的,每个应用程序是我的想法:)如果你真的,真的必须有每个用户的数据,你可以用一个连接到用户的密钥保存数据。但是,除非你真的有性能问题,否则我不推荐缓存。 – Onkelborg 2010-10-21 21:47:05

0

您声明第三个选项是性能命中(完全删除会话对象),但是您尝试过吗?

我问,因为序列化标准数据集is notoriously resource intensive on the server side - 在许多情况下(1MB数据集可能需要10-15MB的序列化)以及处理器执行此操作的时间,内存占用会增加一个数量级。

我真的建议看着尝试3和测试,看看您的问题有充分的理由,或者如果你真的看到一个性能增益;)

如果您在会话存储数据集的设置,那么你应该查看custom serialisation以最大限度地减少存储的数据量。

+1

我没有尝试删除会话对象并重新加载数据,我会试试看。 – NullReference 2010-10-21 21:33:09

+0

正如一个侧面说明,它看起来像使用会话[“数据集”] = dataset.GetXml()会话中存储数据集。不知道这是否与直接序列化不同。 – NullReference 2010-10-21 21:39:18

+0

在proc会话状态不会序列化,但似乎Seralization被迫..虽然.. – Onkelborg 2010-10-21 21:47:55