【发布时间】:2012-02-17 20:46:53
【问题描述】:
ASP.Net 会话看起来非常适合传统的 WebForms 应用程序,但它们所做的一些事情对于现代 AJAX 和 MVC 应用程序来说是一个严重的问题。
具体来说,访问 ASP.Net 提供程序只有 3 种方式:
锁定读写(默认)- 会话从
AcquireRequestState触发锁定,直到ReleaseRequestState触发。如果浏览器一次发出 3 个请求,它们将在服务器上排队。这是 MVC 2 中的唯一选项,但 MVC 3 允许...非锁定只读 - 会话未锁定,但无法保存。这似乎是unreliable though,因为某些读取似乎再次锁定了会话。
会话已禁用 - 任何读取或写入会话的尝试都会引发异常。
但是,对于现代 MVC 应用程序,我会同时发生很多 AJAX 事件 - 我不希望它们在服务器上的队列中,但我确实希望它们能够写入会话。
我想要的是第四种模式:脏读,最后写获胜
我认为(很高兴得到纠正)唯一的方法是完全替换 ASP.Net 的会话。我可以写我的own provider,但 ASP 仍会使用它支持的 3 种模式之一来调用它。有没有办法让 ASP.Net 支持乐观并发?
这让我用一个基本上做同样事情但不锁定的新类替换了对会话的所有调用——这很痛苦。
我希望尽可能多地保留当前会话的内容(最重要的是各种日志中的会话 ID),同时尽量减少代码替换。有没有办法做到这一点?理想情况下,我希望 HttpContext.Current.Session 指向我的新类,但没有 ASP.Net 锁定任何请求。
有没有人做过类似的事情?对于所有的 AJAXey MVC 应用程序来说,这似乎很奇怪,这是 ASP 的一个新问题。
【问题讨论】:
-
如果您编写自己的提供程序。即使 ASP.NET 要求您锁定会话,谁还在强迫您锁定?只需忽略锁定提示并随意进行脏读即可。
-
@HasanKhan - 我认为(我想肯定知道)
SetAndReleaseItemExclusive(保存值的方法)只有在ReleaseRequestState事件期间被调用,如果已应用锁定。如果有某种方法可以欺骗,我想从做过的人那里知道;我不能成为第一个需要乐观并发会话的人,我宁愿不重新发明轮子。 -
“我不希望他们在服务器上的队列,但我确实希望他们能够写入会话。”不,不,你没有。如果他们需要写入会话,他们需要轮流避免不一致的写入。使用选项 3 获取尽可能多的请求,以尽可能减少阻塞,并保持不变。
-
@Ben - 我不关心不一致的写入。正如我在问题中所说的那样,我想要最后写入获胜。对于我的应用程序(我怀疑还有更多)会话包含用户选项(页面大小、当前排序字段、购物篮等)或用于优化的缓存值 - 在任何一种情况下,对于我的应用程序来说,我都会使用 last-write-wins 模型想。我敢肯定有很多应用程序的当前锁定模型是完美的,但我不能是唯一一个在会话中寻找乐观并发的开发人员。
-
@Aristos 就像我一开始说的,锁独占适用于很多情况。我并不是说乐观并发应该是默认的,我是在问其他人是否已经这样做或找到了更好的方法来实现它。
标签: asp.net session concurrency session-state