`
semi_sleep
  • 浏览: 101069 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Summary for hibernate cache

阅读更多

You have the option to tell Hibernate which caching implementation to use by specifying the name of a class that

implements org.hibernate.cache.CacheProvider using the property hibernate.cache.provider_class.


<cache
    usage="transactional|read-write|nonstrict-read-write|read-only"  (1)
    region="RegionName"                                              (2)
    include="all|non-lazy"                                           (3)
/>
(1)  usage (required) specifies the caching strategy: transactional, read-write, nonstrict-read-write or read-only
(2)  region (optional, defaults to the class or collection role name) specifies the name of the second level cache

region
(3)  include (optional, defaults to all) non-lazy specifies that properties of the entity mapped with lazy="true" may

not be cached when attribute-level lazy fetching is enabled


Alternatively (preferably?), you may specify <class-cache> and <collection-cache> elements in hibernate.cfg.xml.


The CacheMode controls how a particular session interacts with the second-level cache.
CacheMode.NORMAL - read items from and write items to the second-level cache
CacheMode.GET - read items from the second-level cache, but don't write to the second-level cache except when updating

data
CacheMode.PUT - write items to the second-level cache, but don't read from the second-level cache
CacheMode.REFRESH - write items to the second-level cache, but don't read from the second-level cache, bypass the effect

of hibernate.cache.use_minimal_puts, forcing a refresh of the second-level cache for all items read from the database


To browse the contents of a second-level or query cache region, use the Statistics API:
Map cacheEntries = sessionFactory.getStatistics()
        .getSecondLevelCacheStatistics(regionName)
        .getEntries();


You'll need to enable statistics, and, optionally, force Hibernate to keep the cache entries in a more human-

understandable format:
hibernate.generate_statistics true
hibernate.cache.use_structured_entries true


Query result sets may also be cached. This is only useful for queries that are run frequently with the same parameters.

To use the query cache you must first enable it:
hibernate.cache.use_query_cache true


Note that the query cache does not cache the state of the actual entities in the result set; it caches only identifier

values and results of value type. So the query cache should always be used in conjunction with the second-level cache.


Most queries do not benefit from caching, so by default queries are not cached. To enable caching, call

Query.setCacheable(true). This call allows the query to look for existing cache results or add its results to the cache

when it is executed.


这里还有一个很容易被忽视的重要问题,即打开查询缓存以后,即使是list方法也可能遇到1+N的问题!相同条件第一次list的时候,因

为查询缓存中找不到,不管class缓存是否存在数据,总是发送一条sql语句到数据库获取全部数据,然后填充查询缓存和class缓存。但

是第二次执行的时候,问题就来了,如果你的class缓存的超时时间比较短,现在class缓存都超时了,但是查询缓存还在,那么list方法

在获取id串以后,将会一个一个去数据库load!因此,class缓存的超时时间一定不能短于查询缓存设置的超时时间!如果还设置了发呆

时间的话,保证class缓存的发呆时间也大于查询的缓存的生存时间。这里还有其他情况,比如class缓存被程序强制evict了,这种情况

就请自己注意了。


缓存策略
只读缓存(read-only):没有什么好说的
读/写缓存(read-write):程序可能要的更新数据
不严格的读/写缓存(nonstrict-read-write):需要更新数据,但是两个事务更新同一条记录的可能性很小,性能比读写缓存好
事务缓存(transactional):缓存支持事务,发生异常的时候,缓存也能够回滚,只支持jta环境,这个我没有怎么研究过


读写缓存和不严格读写缓存在实现上的区别在于,读写缓存更新缓存的时候会把缓存里面的数据换成一个锁,其他事务如果去取相应的缓

存数据,发现被锁住了,然后就直接取数据库查询。
在hibernate2.1的ehcache实现中,如果锁住部分缓存的事务发生了异常,那么缓存会一直被锁住,直到60秒后超时。
不严格读写缓存不锁定缓存中的数据。


Collection的缓存和前面查询缓存的list一样,也是只保持一串id,但它不会因为这个表更新过就失效,一个collection缓存仅在这个

collection里面的元素有增删时才失效。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics