缓存在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,如下代码所示:

实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        /// Creates an <see cref="ICacheConcurrencyStrategy"/> from the parameters.
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        
/// </summary>
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        
/// <param name="usage">The name of the strategy that <see cref="ICacheProvider"/> should use for the class.</param>
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        
/// <param name="name">The name of the class the strategy is being created for.</param>
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        
/// <param name="mutable"><c>true</c> if the object being stored in the cache is mutable.</param>
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        
/// <returns>An <see cref="ICacheConcurrencyStrategy"/> to use for this object in the <see cref="ICache"/>.</returns>
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        // was private in h2.1
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)
        public static ICacheConcurrencyStrategy CreateCache( string usage, string name, bool mutable )
{
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)            
if( log.IsDebugEnabled )
{
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                log.Debug( 
"cache for: " + name + "usage strategy: " + usage );
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)            }

实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)            ICacheConcurrencyStrategy ccs 
= null;
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)            
switch( usage )
{
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                
case CacheFactory.ReadOnly:
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    
if( mutable )
{
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                        log.Warn( 
"read-only cache configured for mutable: " + name );
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    }

实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    ccs 
= new ReadOnlyCache();
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    
break;
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                
case CacheFactory.ReadWrite:
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    ccs 
= new ReadWriteCache();
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    
break;
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                
case CacheFactory.NonstrictReadWrite:
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    ccs 
= new NonstrictReadWriteCache();
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    
break;
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                
default:
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)                    
throw new MappingException( "cache usage attribute should be read-write, read-only, nonstrict-read-write, or transactional" );
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)            }

实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)            
return ccs;
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)
实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)        }

  可以看出,这样的实现是一个非常优秀的设计,意味着非常强大的扩展性与可维护性。
  在NHibernate的缓存方案中,使用了锁模式进行管理,它的实现是模仿操作系统中的“原语”进行的,是一个基于线程安全的实现的方案,具体的管理方式类似PV操作的形式。

相关文章:

  • 2021-09-11
  • 2021-06-26
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-01
  • 2022-01-15
猜你喜欢
  • 2021-12-06
  • 2021-05-31
  • 2021-05-19
  • 2021-07-31
  • 2021-07-03
  • 2021-06-27
相关资源
相似解决方案