我有一个C#.NET应用程序,其会话状态由DynamoDB支持。但是,我注意到我期望的吞吐量更高。但是我在实际表中注意到所有内容都作为SessionItems存储在一个长字符串中。
但是,让我们说我在会话中存储多件事
Http.Context.Session["Object1"] = obj1;
Http.Context.Session["Object2"] = obj2;
obj1
和obj2
是两个不同类的实例。
现在当我去读或写其中一个时,例如::
var obj1 = Http.Context.Session["Object1"];
是否正在读取DynamoDB表中SessionItems
中存储的所有内容?这个解释可以解释桌面上更高的吞吐量,但似乎非常不必要。
答案 0 :(得分:1)
理想情况下,ASP.NET会在每个请求(例如页面/控制器)上对用户会话中存储的对象的序列化集合执行单次读取和单次写入。如果您在请求中访问该集合中的多个项目,它将使用本地副本,而不必访问基础数据存储区。
但是,我认为你注意到的是ASP.NET的pessimistic locking model。当它尝试执行单个读取以检索用户的会话数据时,如果该用户的会话数据已经设置了锁定,它将不断重试检索它(每500毫秒)。
ASP.NET HTTP生命周期的细节取决于框架版本等,但一般概念是这样的:
如果有多个HTTP请求访问用户的会话(例如页面上的Ajax),您会注意到由于排他锁而没有并发 - 如果为每个请求启用Session
,它们将以串行方式执行。 (即使他们没有明确访问Session
)。
避免这种情况的一种方法是有意识地写入Session
的位置,并在所有其他页面/控制器上指定SessionStateBehavior.ReadOnly
。执行此操作时,ASP.NET不会设置独占锁(将使用GetItem而不是GetItemEx)。请参阅ASP.NET Session State Overview。
页:
<% @Page EnableSessionState="ReadOnly" %>
控制器:
[SessionState(SessionStateBehavior.ReadOnly)]
参考:
希望这有帮助!
此致
罗斯