1. 首先我介绍下什么是NHibernate.Caches.Prevalence,它是一个基于Bamboo.Prevalence.dll、Bamboo.Prevalence.Util.dll上的Spring.NET的缓存配置类库。Bamboo.Prevalence是一个object prevalence 概念的.NET 实现,由Prevayler的Klaus Wuestefeld发起。Bamboo.Prevalence 向针对CLR的确定系统提供透明的object persistence。官方下载地址可查看:http://sourceforge.net/projects/bbooprevalence/
它可产生一系列的缓存目录,通过缓存目录可以从文件中获取数据,并且在缓存目录中通过Snapshot,也就是快照,可以进行断点保存。
2. 现在我们来看下Spring.NET如何配置它的,在上一篇(http://www.cnblogs.com/liping13599168/archive/2010/12/17/1909093.html)已经有做过了些介绍:
代码
<!--
启用二级缓存配置
-->
<
entry
key
="cache.use_second_level_cache"
value
="true"
/>
<
entry
key
="cache.use_query_cache"
value
="true"
/>
<!--
Prevalence缓存机制
-->
<
entry
key
="cache.provider_class"
value
="NHibernate.Caches.Prevalence.PrevalenceCacheProvider, NHibernate.Caches.Prevalence"
/>
<!--
设置物理缓存文件的存放位置(目前不支持相对路径)
-->
<
entry
key
="prevalenceBase"
value
="D:\caches"
/>
其中presvalenceBase必须设置物理路径,如果不设置这个参数,它默认的物理路径为:C:\Windows\system32\inetsrv,当然您也可以通过改下NHibernate.Caches.Prevalence.dll中的 PrevalenceCacheProvider 类,即private static string GetDataDirFromConfig(string region, IDictionary<string, string> properties)方法,进行改写。比如您可以自定义一个继承于ICacheProvider接口的MyPrevalenceCacheProvider。
3. 然后在EntityCacheStrategies配置节点中配置以下信息:
代码
<!--
缓存策略属性
-->
<
object
id
=
"
EntityCacheStrategies
"
type
=
"
Spring.Util.Properties
"
>
<!--
read
-
only
|
read
-
write
|
nonstrict
-
read
-
write
|
transactional
-->
<
property name
=
"
['TestWebServer.Model.TblEnterprise,TestWebServer.Model']
"
value
=
"
read-write
"
/>
</
object
>
4. 在我的数据DAO上这样写:
public
ITblEnterprise GetInfo(
int
id)
{
return GetInfoById(id);
}
public
TIModel GetInfoById(
object
id)
{
return
(TIModel)HibernateTemplate.Get
<
TModel
>
(id);
}
通过页面测试,调用后得到得到一个缓存目录:

并且在5分钟后,就会自动产生一个snapshot:

为什么是5分钟呢?请看源代码:
代码
private
void
SetupEngine()
{
this
.engine
=
PrevalenceActivator.CreateTransparentEngine(
typeof
(CacheSystem),
this
.dataDir);
this
.system
=
this
.engine.PrevalentSystem
as
CacheSystem;
this
.taker
=
new
SnapshotTaker(
this
.engine, TimeSpan.FromMinutes(
5.0
), CleanUpAllFilesPolicy.Default);
}
可以看出这里使用了一个时间参数,TimeSpan.FromMinutes(5.0),而SnapshotTaker内部使用了一个计时器,每隔5分钟就会自动产生一个snapshot
代码
private
void
OnTimer(
object
state)
{
PrevalenceEngine engine
=
(PrevalenceEngine) state;
try
{
engine.TakeSnapshot();
this
.DeleteFiles(
this
._cleanUpPolicy.SelectFiles(engine));
}
catch
(Exception)
{
}
}
注:您也可以通过重写它的类对于这个间隔时间进行配置。因为原先的代码是定死掉的。
5. 注意到ICacheProvider接口上有两个方法:Start以及Stop。这两个分别都会在ISessionFactory构造期间和ISessionFactory关闭的时候将进行调用。
而PrevalenceCacheProvider,在Start和Stop都有具体的实现。思路很简单,Start就是创建相关的缓存目录,Stop就是销毁缓存目录。如果你想实现销毁缓存目录的时候,可以在Global.asax中的Application_End事件中实现,既然ISessionFactory在关闭的时候,会调用Stop方法,那么就这样写:
代码
//
关闭SessionFactory,主要目的是为了清除PrevalenceCache产生的缓存目录
Spring.Context.IApplicationContext context
=
Spring.Context.Support.ContextRegistry.GetContext();
NHibernate.ISessionFactory sessionFactory
=
(NHibernate.ISessionFactory)context.GetObject(
"
NHibernateSessionFactory
"
);
sessionFactory.Close();
其中NHibernateSessionFactory是定义在XML配置文件中的对象。这样就能够销毁缓存目录了。
至于Bamboo.Prevalence的相关应用,可以参考它的官方网站下载源代码。