asp.net - 完全替换 ASP.Net 的 session

标签 asp.net session concurrency session-state

ASP.Net session 对于传统的 WebForms 应用程序来说似乎是完美的,但它们所做的一些事情对于现代 AJAX 和 MVC 应用程序来说是一个严重的问题。

具体来说,只有 3 种方法可以访问 ASP.Net 提供程序:

  • 锁定读写 (默认)- session 从 AcquireRequestState 锁定射击直到 ReleaseRequestState火灾。如果浏览器一次发出 3 个请求,它们将在服务器上排队。这是 MVC 2 中的唯一选项,但 MVC 3 允许...
  • 非锁定只读 - session 未锁定,但无法保存。这似乎是 unreliable though ,因为某些读取似乎再次锁定了 session 。
  • session 已禁用 - 任何读取或写入 session 的尝试都会引发异常。

  • 但是,对于现代 MVC 应用程序,我有很多 AJAX 事件同时发生——我不希望它们在服务器上的队列中,但我确实希望它们能够写入 session 。

    我想要的是第四种模式:脏读,最后写胜

    我认为(很高兴得到纠正)这样做的唯一方法是完全替换 ASP.Net 的 session 。我可以写我的own provider ,但 ASP 仍会使用它支持的 3 种模式之一来调用它。有没有办法让 ASP.Net 支持乐观并发?

    这让我用一个基本上做同样事情但不锁定的新类替换了对 session 的所有调用——这很痛苦。

    我想尽可能多地保留当前 session 的内容(最重要的是各种日志中的 session ID),并以最少的代码替换。有没有办法做到这一点?理想情况下,我想要 HttpContext.Current.Session指向我的新类(class),但没有 ASP.Net 锁定任何请求。

    有没有人已经做过这样的事情?对于所有的 AJAXey MVC 应用程序来说,这似乎是 ASP 的一个新问题,这似乎很奇怪。

    最佳答案

    首先,我说 MS asp.net 已锁定“asp.net 处理页面” session 的核心,位于 asp.net 4 的“ webengine4.dll ”dll 中的某处

    我说的是从 MS asp.net act correct and lock the session this way 的角度来看因为asp.net 无法知道我们在 session 中保留什么类型的信息,所以可以做出正确的“最后写入获胜”。

    同样正确的是锁 session 整页因为这种方式为您的程序提供了非常重要的同步,从现在的经验来看,我说您的大部分操作都需要它。在我用我的替换 ms session 后,在我的所有操作上我都需要进行全局锁定,否则我会遇到双重插入、双重操作等问题。

    我给 一个例子我在这里认识到的问题。 session 数据保存在作为键列表的 SessionSateItemCollection 上。当 session 读取或写入此集合时,将它们全部一起完成。那么让我们看看这个案例。

    我们在 session 中有树变量,“VAR1”,“VAR2”,“VAR3”

    第 1 页。
    getsession(实际上是获取所有数据并将它们放在列表中)
    session [VAR1] = "数据1";
    保存 session ()
    结果是 VAR1=data1, VAR2=(var2 的最后一个数据), VAR3=(var3 的最后一个数据)

    第 2 页。
    getsession(实际上是获取所有数据并将它们放在列表中)
    session [VAR2] = "数据2";
    保存 session ()
    结果是 VAR1=(var1 的最后一个数据), VAR2=data2, VAR3=(var3 的最后一个数据)

    第 3 页。
    getsession(实际上是获取所有数据并将它们放在列表中)
    session [VAR3] = "data3";
    保存 session ()
    结果是 VAR1=(var1 的最后一个数据), VAR2=(var2 的最后一个数据) VAR3="data3"

    请注意,每个页面都有数据的克隆,因为他从 session 介质中读取它们(例如,当它们最后从数据库中读取时)

    如果我们让这 3 个页面在没有锁定的情况下运行,我们实际上并没有脏读,下界“最后写入获胜” - 我们这里有“ 最后写入破坏其他的 ”,因为如果你认为再说一遍,当 VAR1 改变时,为什么 VAR2 和 VAR3 保持不变?如果您在其他地方更改了 VAR2 怎么办。

    出于这个原因,我们不能让这个没有锁定。

    现在用 20 个变量对其进行成像……完全一团糟。

    可能的解决方案

    由于许多池的 asp.net 的多线程,跨池和跨计算机保持相同数据的唯一方法是拥有一个公共(public)数据库,或者像 asp.net 状态服务这样的所有进程程序通用的。

    我选择拥有一个通用数据库,这比为该建议创建程序更容易。

    现在如果我们连接 cookies 我们制造的,给用户 给 session 的数据用户 , 我们使用一个完全自定义的数据库字段来控制数据,我们知道我们喜欢锁定什么,不知道什么,如何保存或更改,或者比较和保留最后写入的 win 数据,我们可以使这项工作,并完全禁用asp.net session 是为所有需求而设计的通用 session 保持器,但不是为处理像这样的特殊情况而设计的。

    asp.net 可以在 future 的版本中使这项工作,是的,他可以通过制作一个名为脏的额外字段,并在 session 保存数据,使用脏字段或类似的东西进行数据合并,但不能做到这一点现在按原样工作 - 至少从我到现在为止的发现。
    实际上 SessionStateItem 在属性上有一个脏标志,但没有在保存数据结束时进行此合并。如果其他人想为现有的 ms asp.net session 状态保持器提供解决方案,我会非常喜欢,我正在写到目前为止我发现的内容,但这并不意味着肯定没有办法 - 我没有按原样找到它。

    希望对大家有所帮助:)

    自定义 SessionStateModule

    在这个答案https://stackoverflow.com/a/3660837/159270 James 在编写自定义模块后说:我仍然无法相信 ASP.Net Session 的自定义实现会锁定整个请求的 session 。

    关于asp.net - 完全替换 ASP.Net 的 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8989648/

    相关文章:

    c# - ASP.Net-Core 中的自定义身份验证

    c# - 对 HttpContext.Current.Session 的静态引用是否为所有用户返回相同的 session ?

    java - 如何检查 servlet 中的 sessionId 是否有效 (java)

    asp.net - ASP.NET session 中的共享方法

    java - java中静态变量的线程安全

    c# - 在 ASP.NET MVC 项目中使用 Serilog

    javascript - 在 Javascript 中获取 ClientID

    asp.net - 如何从 pdf 文件中删除或禁用超链接事件?

    django - 使用 Django session 存储登录用户

    java - 有条件地定义同步块(synchronized block)