转载:http://www.cnblogs.com/william_fire/articles/126646.html
缓存在O/R Mapping组件中是非常重要的,一个比较好的缓存方案,可以大大地提高对象的使用效率,避免内存空间上的浪费。目前需要在构思架构部分,但缓存的实现 方式突然吸引了我,所以就对缓存进行一些思考,并研究了Gentle.NET与NHibernate的实现原理。 [这里的研究基于NHibernate 0.7.0]
NHibernate的实现方案
在NHibernate上,缓存的机制实现充分考虑了性能与扩展性,它与Gentle.NET在实现不同的是全部是基于Hashtable而 非HybridDictionary。一开始,我看见这样的实现的时候,还误以为,NHibenate过于模仿Java,而没有充分利用.NET的特性, 然而,在仔细分析之后,发现直接使用Hashtable是一个非常好的思路。
因为在HybridDictionary中,当插入一个新的对象到集合中时,该类会进行一个判断,如果集合中的元素多于9个时,则切换为 Hashtable模式,这看起来非常有意思。但实际上,在O/R Mapping中,集合的数量往往都是比较多的,尤其是在企业应用中,由于网络传输数据的延迟,缓存的实现是一个非常珍贵的资源,它大大的减轻了数据库服 务端的压力。就这个层次上来说,实际上实现ListDictionary并没有太大的意义。
NHibernate的缓存机制,比起Gentle.NET来说,要复杂一些。NHibernate中,缓存对象的创建实际上通过 CacheFactory产生的。这样做的原因是,在NHibernate中,缓存包括ReadOnlyCache、ReadWriteCache、 NonstrictReadWriteCache这三种缓存管理类,它们都继承自ICacheConcurrencyStrategy接口,可以非常方便 地添加应用了新策略的缓存管理类。
另外,在NHibernate中,缓存对象的类型也并不是不可变的,在现有的设计上,使用了 HashtableCacheProvider与HashtableCache两个类来描述Provider对象和Cache对象,分别继承于 ICacheProvider与ICache,如下代码所示:
/// Creates an <see cref="ICacheConcurrencyStrategy"/> from the parameters.
/// </summary>
/// <param name="usage">The name of the strategy that <see cref="ICacheProvider"/> should use for the class.</param>
/// <param name="name">The name of the class the strategy is being created for.</param>
/// <param name="mutable"><c>true</c> if the object being stored in the cache is mutable.</param>
/// <returns>An <see cref="ICacheConcurrencyStrategy"/> to use for this object in the <see cref="ICache"/>.</returns>
// was private in h2.1
public static ICacheConcurrencyStrategy CreateCache( string usage, string name, bool mutable )
{
if( log.IsDebugEnabled )
{
log.Debug( "cache for: " + name + "usage strategy: " + usage );
}
ICacheConcurrencyStrategy ccs = null;
switch( usage )
{
case CacheFactory.ReadOnly:
if( mutable )
{
log.Warn( "read-only cache configured for mutable: " + name );
}
ccs = new ReadOnlyCache();
break;
case CacheFactory.ReadWrite:
ccs = new ReadWriteCache();
break;
case CacheFactory.NonstrictReadWrite:
ccs = new NonstrictReadWriteCache();
break;
default:
throw new MappingException( "cache usage attribute should be read-write, read-only, nonstrict-read-write, or transactional" );
}
return ccs;
}
可以看出,这样的实现是一个非常优秀的设计,意味着非常强大的扩展性与可维护性。
在NHibernate的缓存方案中,使用了锁模式进行管理,它的实现是模仿操作系统中的“原语”进行的,是一个基于线程安全的实现的方案,具体的管理方式类似PV操作的形式。