20.2. 二级缓存(The Second Level Cache)
Hibernate 的
Session
在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或 JVM 级别(SessionFactory 级别
)的缓存。你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。
通过在
hibernate.cache.provider_class
属性中指定 org.hibernate.cache.CacheProvider
的某个实现的类名,你可以选择让 Hibernate 使用哪个缓存实现。Hibernate 打包一些开源缓存实现,提供对它们的内置支持(见下表)。除此之外,你也可以实现你自己的实现,将它们插入到系统中。注意,在 3.2 版本之前,默认使用 EhCache 作为缓存实现,但从 3.2 起就不再这样了。
表 20.1. 缓存策略提供商(Cache Providers)
Cache Provider class Type Cluster Safe Query Cache Supported Hashtable (not intended for production use) org.hibernate.cache.HashtableCacheProvider
memory yes EHCache org.hibernate.cache.EhCacheProvider
memory,disk yes OSCache org.hibernate.cache.OSCacheProvider
memory,disk yes SwarmCache org.hibernate.cache.SwarmCacheProvider
clustered (ip multicast) yes (clustered invalidation) JBoss Cache 1.x org.hibernate.cache.TreeCacheProvider
clustered (ip multicast), transactional yes (replication) yes (clock sync req.) JBoss Cache 2 org.hibernate.cache.jbc.JBossCacheRegionFactory
clustered (ip multicast), transactional yes (replication or invalidation) yes (clock sync req.)
20.2.1. 缓存映射(Cache mappings)
类或者集合映射的“<cache>
元素”可以有下列形式:
<cache
usage="transactional|read-write|nonstrict-read-write|read-only"
region="RegionName"
include="all|non-lazy"
/>
usage
(必须)说明了缓存的策略:transactional
、 read-write
、nonstrict-read-write
或 read-only
。
region
(可选,默认为类或者集合的名字(class or collection role name)) 指定第二级缓存的区域名(name of the second level cache region)
include
(可选,默认为 all
) non-lazy
当属性级延迟抓取打开时,标记为 lazy="true"
的实体的属性可能无法被缓存
另外(首选?),你可以在hibernate.cfg.xml
中指定 <class-cache>
和 <collection-cache>
元素。
这里的 usage
属性指明了缓存并发策略(cache concurrency strategy)。
20.2.2. 策略:只读缓存(Strategy:read only)
如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读
缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。
<class name="eg.Immutable" mutable="false">
<cache usage="read-only"/>
....
</class
>
20.2.3. 策略:读写/缓存(Strategy:read/write)
如果应用程序需要更新数据,那么使用读/写缓存
比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。 如果在 JTA 环境中使用缓存,你必须指定 hibernate.transaction.manager_lookup_class
属性的值, 通过它,Hibernate 才能知道该应用程序中 JTA 的TransactionManager
的具体策略。 在其它环境中,你必须保证在 Session.close()
、或 Session.disconnect()
调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate 内置的缓存策略并不支持锁定功能。
<class name="eg.Cat" .... >
<cache usage="read-write"/>
....
<set name="kittens" ... >
<cache usage="read-write"/>
....
</set>
</class
>
20.2.4. 策略:非严格读/写缓存(Strategy:nonstrict read/write)
如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存
策略。如果在 JTA 环境中使用该策略,你必须为其指定 hibernate.transaction.manager_lookup_class
属性的值,在其它环境中,你必须保证在Session.close()
、或 Session.disconnect()
调用前,整个事务已经结束。
20.2.5. 策略:事务缓存(transactional)
Hibernate 的事务缓存
策略提供了全事务的缓存支持,例如对 JBoss TreeCache 的支持。这样的缓存只能用于 JTA 环境中,你必须指定为其 hibernate.transaction.manager_lookup_class
属性。
20.2.6. 各种缓存提供商/缓存并发策略的兼容性
重要
没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。
没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。
表 20.2. 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support)
Cache read-only nonstrict-read-write read-write transactional Hashtable (not intended for production use) yes yes yes EHCache yes yes yes OSCache yes yes yes SwarmCache yes yes JBoss Cache 1.x yes yes JBoss Cache 2 yes yes