2011-05-04 32 views
0

对于缓存,nhibernate和涉及这两者的所有内容,我都是一个完整的新手,所以这个问题可能过于愚蠢。使用nHibernate/ASP.NET缓存一致性与静态对象

我有我的系统中的多个其他对象使用的对象的某些实例。因此,例如..

class Template { 
    // lots of data 
} 

class One { 
    IList<Template> Templates { get; set; } 
} 
class Two { 
    IList<Template> Templates { get; set; } 
} 
class Three { 
    IList<Template> Templates { get; set; } 
} 

现在,届时,Template某些情况下会使用非常,非常频繁。 (每20秒思考一次),它包含了很多需要数学计算的东西。

我的问题基本上是哪种方法对我的数据库/服务器的压力最小。

我最好只在nHibernate中将所有内容都留在Level 2缓存中吗?或者我更明智地检索Template对象,并在我的ASP.NET应用程序启动时将其存储在一个静态变量中,并在该变量更新时刷新该变量?

我已经看过一些其他类似的问题,但我仍然在黑暗中。关于缓存的大部分文档都假设了大量有关该主题的知识,因此我很难区分哪些是最佳流程。

回答

2

每20秒钟一次听起来不是很有压力。您需要重新考虑更新数据的需求,以及您可以在数据库中承受的压力。

二级缓存在这种情况下不一定能帮助你,因为你使用了对象集合。为了知道它需要哪个对象,它仍然需要查询数据库,如果你这样做,它甚至可能会获取数据(除非实体中有很多原始数据)。

你基本上有三种不同的选择:

1级高速缓存 对于每个连接/会话,你做,NHibernate的会永远缓存,它具有获取的唯一实体。每当你试图获得一个基于它的标识符(主键)的实体时,它将首先检查它的一级缓存。这并不适用于实体集合不过,除非你可以强制NHibernate的只得到“标识符”的收集和让他们一个一个(通常很慢)

二级缓存 这缓存将可用对于每个连接/会话,并尝试在数据库访问数据库之前从缓存中获取数据。与第一级缓存相同的规则适用,除非已经加载,否则无法在不查询数据库的情况下将实体集合收集到实体中。

自定义缓存 您可以随时取不过缓存你自己,照顾,这样,你需要你的类相应的模型(具有存储模板对象,并集合只跟踪标识符,而不是模板对象) 。如果你像这样重构,二级和一级缓存仍然同样有用。

我会给你,说明你就是我讲一个例子:

如果一个包含标识模板[1,2,3,4] 两个包含标识模板[2,3] 三个包含带标识符的模板[3,4,5]

为了让NHibernate知道一个需要模板1,2,3,4,它需要查询数据库。 1,2,3,4将在这里单独缓存。 为了真正知道两个需要实体2和3,它仍然需要查询数据库。它不可能知道2,3也是Two中的集合的一部分。 Si不会从缓存中获取它们,因为它将选择属于类别2的模板对象,因此会选择完整的数据。这就是为什么缓存无法帮助你。

我认为您需要提供更多关于您将要处理的数据类型的详细信息,以及如何存储和更新数据以获得有用的答案。

+0

谢谢。这很有意义,它清除了我关于缓存的很多问题。这可能在其他地方列出,但我没有找到它。 – Ciel 2011-05-05 13:12:17

+0

_我想你需要给出更多的细节,说明你将要处理什么类型的数据,以及如何存储和更新数据以便得到一个有用的答案。 - 其实你回答得非常好你的描述。目标是防止对数据库造成压力,缓存工作的方式只能用于那些不经常更改的数据。所以我需要将我的'Templates'抽象为两种类型,其中一个将被缓存在数据库中,另一个将在程序启动时被缓存为静态变量。 – Ciel 2011-05-05 13:16:51

1

静态变量会减少服务器上的压力,但是这会施加一些限制,具体来说,如果您不需要缩放,那么缩放将变得更加困难(Web园区/农场),这是您的选择'寻找