“每个请求的会话”模式是不是利用了缓存? (“每个会话的会话”或“每个请求的会话”)

Posted

技术标签:

【中文标题】“每个请求的会话”模式是不是利用了缓存? (“每个会话的会话”或“每个请求的会话”)【英文标题】:Does the "session per request" pattern take advantage of the cache? ("Session per session" or "Session per request")“每个请求的会话”模式是否利用了缓存? (“每个会话的会话”或“每个请求的会话”) 【发布时间】:2012-09-23 16:51:34 【问题描述】:

这几天我在一个 Web 应用程序中从头开始构建一个新应用程序。 (技术是Asp.Net,我使用的ORM是Entity Framework。如果重要的话)

我不确定广泛使用的模式 session per request 是否真的很好。 在我看来,该模式的优点是缓存不会增加,直到数据库会话崩溃\太大,因此效率低下。

但是每个请求的新会话不是太多了吗?这意味着每次服务器调用都会重置缓存,即使是像自动完成这样简单的 ajax 请求也会有一个全新的缓存,实际上每次按键都会重置缓存。

您在一个请求中查询相同的对象实体行的可能性很小。

Session per session 不是更好的模式吗?两全其美的意思

    缓存不会永远增长。 缓存其实可以用...

那么... 为什么每个请求的会话被如此广泛地使用而每个会话的会话却不是?


说明:

    当我编写 ORM 会话时,它同时适用于 NHibernate's sessionEntityFramework's DbContext。 我的意思是在每个请求上刷新 session\dbcontext 的提交保存更改。

【问题讨论】:

【参考方案1】:

每个请求的会话模式对于与 ORM 一起使用更加自然和健壮。它获得脏实体的机会更小,并且具有更可预测的资源管理。

如果我没听错,你的意思是 Session 下的 DbContext 实例比 Session Per Session 只能在应用程序中使用而无需修改数据,否则当其他请求执行数据修改时,您会收到一个请求提交的意外数据。另外我不确定实体框架上下文是线程安全的 - 而处理请求是多线程的。

我不完全确定,但我认为 Entity Framework 并没有像您期望的那样广泛使用缓存(== 标识映射)。在选择实体集时,即使所有数据都在缓存中,它也会查询数据库——它只能避免构造新实体,而是使用身份映射中的现有实体。

对于缓存还有其他解决方案,它们更好。

【讨论】:

1.是的,我的意思是 EntityFramework-DbContextNHibernate-我写 session 时的会话;我的最后一个应用程序使用 Nhibernate... 2. 关于脏数据,我的意思是在每个请求上刷新 session\dbcontext 的提交保存更改。 关于意外保存-前一个请求运行时可能会出现其他请求-当数据已被修改但尚未提交时,它可以在第一个请求之前调用提交。但一般来说,如果您的 ORM 支持对会话实例的并发和线程安全访问,那么每个会话的会话可能是一个解决方案。但我认为性能不会明显提高。【参考方案2】:

对我来说,这一切都是为了通过将一个工作单元限制为一个请求来提供一致性。我不确定当出现问题时每个会话的会话如何工作。

例如,如果处理了多个请求,然后您在提交时收到乐观并发异常,您会怎么做?那时您可能会遇到多个合并冲突。

因此,每个请求的会话只会限制您的冲突暴露,并使工作单元在请求范围内。

【讨论】:

我同意,即使使用事务,在持久操作失败的情况下,也很难在上下文中支持数据库和实体之间的一致性。大多数 ORM 不保证这一点。

以上是关于“每个请求的会话”模式是不是利用了缓存? (“每个会话的会话”或“每个请求的会话”)的主要内容,如果未能解决你的问题,请参考以下文章

Nhibernate in asp,net ISession 帮助

Facebook Messenger Bot:会话变量

带有 Ninject 的 NHibernate 会话管理

使用 Apollo 和 GraphQL 缓存而不是 Vuex?

Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式

LRU缓存机制的实现