一、hibernate的二级缓存
 
   如果开启了二级缓存,hibernate在执行任何一次查询的之后,都会把得到的结果集放到缓存中,缓存结构可以看作是一个hash table,key是数据库记录的id,value是id对应的pojo对象。当用户根据id查询对象的时候(load、iterator方法),会首先在缓存中查找,如果没有找到再发起数据库查询。但是如果使用hql发起查询(find, query方法)则不会利用二级缓存,而是直接从数据库获得数据,但是它会把得到的数据放到二级缓存备用。也就是说,基于hql的查询,对二级缓存是只写不读的。
 
   针对二级缓存的工作原理,采用iterator取代list来提高二级缓存命中率的想法是不可行的。Iterator的工作方式是根据检索条件从数据库中选取所有目标数据的id,然后用这些id一个一个的到二级缓存里面做检索,如果找到就直接加载,找不到就向数据库做查询。因此假如iterator检索100条数据的话,最好情况是100%全部命中,最坏情况是0%命中,执行101条sql把所有数据选出来。而list虽然不利用缓存,但是它只会发起1条sql取得所有数据。在合理利用分页查询的情况下,list整体效率高于iterator。
 
   二级缓存的失效机制由hibernate控制,当某条数据被修改之后,hibernate会根据它的id去做缓存失效操作。基于此机制,如果数据表不是被hibernate独占(比如同时使用JDBC或者ado等),那么二级缓存无法得到有效控制。
 
   由于hibernate的缓存接口很灵活,cache provider可以方便的切换,因此支持cluster环境不是大问题,通过使用swarmcache、jboss cache等支持分布式的缓存方案,可以实现。但是问题在于:
 
   1、 分布式缓存本身成本偏高(比如使用同步复制模式的jboss cache)
 
   2、 分布式环境通常对事务控制有较高要求,而目前的开源缓存方案对事务缓存(transaction cache)支持得不够好。当jta事务发生会滚,缓存的最后更新结果很难预料。这一点会带来很大的部署成本,甚至得不偿失。
 
   结论:不应把hibernate二级缓存作为优化的主要手段,一般情况下建议不要使用。
 
   原因如下:
 
   1、 由于hibernate批量操作的性能不如sql,而且为了兼容1.0的dao类,所以项目中有保留了sql操作。哪些数据表是单纯被hibernate独占无法统计,而且随着将来业务的发展可能会有很大变数。因此不宜采用二级缓存。
 
   2、 针对系统业务来说,基于id检索的二级缓存命中率极为有限,hql被大量采用,二级缓存对性能的提升很有限。
 
   3、 hibernate 3.0在做批量修改、批量更新的时候,是不会同步更新二级缓存的,该问题在hibernate 3.2中是否仍然存在尚不确定。
 
   二、hibernate的查询缓存
 
   查询缓存的实现机制与二级缓存基本一致,最大的差异在于放入缓存中的key是查询的语句,value是查询之后得到的结果集的id列表。表面看来这样的方案似乎能解决hql利用缓存的问题,但是需要注意的是,构成key的是:hql生成的sql、sql的参数、排序、分页信息等。也就是说如果你的hql有小小的差异,比如第一条hql取1-50条数据,第二条hql取20-60条数据,那么hibernate会认为这是两个完全不同的key,无法重复利用缓存。因此利用率也不高。
 
   另外一个需要注意的问题是,查询缓存和二级缓存是有关联关系的,他们不是完全独立的两套东西。假如一个查询条件hql_1,第一次被执行的时候,它会从数据库取得数据,然后把查询条件作为key,把返回数据的所有id列表作为value(请注意仅仅是id)放到查询缓存中,同时整个结果集放到class缓存(也就是二级缓存),key是id,value是pojo对象。当你再次执行hql_1,它会从缓存中得到id列表,然后根据这些列表一个一个的到class缓存里面去找pojo对象,如果找不到就向数据库发起查询。也就是说,如果二级缓存配置了超时时间(或者发呆时间),就有可能出现查询缓存命中了,获得了id列表,但是class里面相应的pojo已经因为超时(或发呆)被失效,hibernate就会根据id清单,一个一个的去向数据库查询,有多少个id,就执行多少个sql。该情况将导致性能下降严重。
 
   查询缓存的失效机制也由hibernate控制,数据进入缓存时会有一个timestamp,它和数据表的timestamp对应。当hibernate环境内发生save、update等操作时,会更新被操作数据表的timestamp。用户在获取缓存的时候,一旦命中就会检查它的timestamp是否和数据表的timestamp匹配,如果不,缓存会被失效。因此查询缓存的失效控制是以数据表为粒度的,只要数据表中任何一条记录发生一点修改,整个表相关的所有查询缓存就都无效了。因此查询缓存的命中率可能会很低托福答案 www.yztrans.com
 
   结论:不应把hibernate二级缓存作为优化的主要手段,一般情况下建议不要使用。
 
   原因如下:
 
   1、 项目上层业务中检索条件都比较复杂,尤其是涉及多表操作的地方。很少出现重复执行一个排序、分页、参数一致的查询,因此命中率很难提高。
 
   2、 查询缓存必须配合二级缓存一起使用,否则极易出现1+N的情况,否则性能不升反降
 
   3、 使用查询缓存必须在执行查询之前显示调用Query.setCacheable(true)才能激活缓存,这势必会对已有的hibernate封装类带来问题。
 
   总结
 
   详细分析hibernate的二级缓存和查询缓存之后,在底层使用通用缓存方案的想法基本上是不可取的。比较好的做法是在高层次中(业务逻辑层面),针对具体的业务逻辑状况手动使用数据缓存,不仅可以完全控制缓存的生命周期,还可以针对业务具体调整缓存方案提交命中率。Cluster中的缓存同步可以完全交给缓存本身的同步机制来完成。比如开源缓存swarmcache采用invalidate的机制,可以根据用户指定的策略,在需要的时候向网络中的其他swarmcache节点发送失效消息,建议采用 www.lefeng123.com

转载于:https://www.cnblogs.com/tianchaoy/p/3571380.html

不要依赖hibernate的二级缓存相关推荐

  1. hibernate教程--二级缓存详解

    Hibernate的二级缓存 一.缓存概述 缓存(Cache): 计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储 ...

  2. hibernate的二级缓存

    缓存(Cache): 计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数 ...

  3. 【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示

    转自:https://blog.csdn.net/eson_15/article/details/51405911 网上商城首页都有热门商品,那么这些商品的点击率是很高的,当用户点击某个热门商品后需要 ...

  4. redis作为hibernate的二级缓存

    hibernate的二级缓存有好多,像ehcache.不过项目的缓存使用的是redis,而redis官方没有实现hibernate的二级缓存接口,只得自己实现.看看公司的高手如何做的吧. 先看配置: ...

  5. (转)为Spring集成的Hibernate配置二级缓存

    http://blog.csdn.net/yerenyuan_pku/article/details/52896195 前面我们已经集成了Spring4.2.5+Hibernate4.3.11+Str ...

  6. hibernate开启二级缓存

    一.在hibernate.cfg.xml中加入: <!-- 开启二级缓存 --> <property name="hibernate.cache.use_query_cac ...

  7. Hibernate中二级缓存配置

    实体类 : 1 package cn.happy.entity; 2 public class Emp { 3 private Integer empNo; 4 private String empN ...

  8. hibernate使用二级缓存ehcahe的配置

    学习hibernate二级缓存的时候,运行程序报了这样的异常: org.hibernate.service.spi.ServiceException: Unable to create request ...

  9. hibernate Search 继续研究 增加 hibernate memcache 二级缓存 配置成功 附件maven代码(2)...

    首先安装 memecached 服务端: 之前写过的 文章,centos 安装memcached服务 : http://toeo.iteye.com/blog/1240607 然后 在 前几天的 弄的 ...

最新文章

  1. 【转】启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法!...
  2. java和python哪个好就业2020-Python和JAVA的就业前景哪个好点?
  3. word2013 blog test
  4. shell -- shift用法
  5. python load_Python实例:numpy.load()的使用
  6. 24-hadoop-hiveserver2jdbc-正则数据导入
  7. android xml 未能解析文件,Android Studio提示“无法解析符号”,但项目已编译
  8. CVPR 2021|可操控的GAN——Hijack-GAN
  9. 如何在linux下通过ssh运行X图形软件
  10. 这就是数据分析之numpy
  11. Sublime个性化配置
  12. mui ajax的值php怎样获取,关于mui.ajax的设置,以及php取不到data值的问题的方法
  13. 竖版1:2500万标准中国地图
  14. ios wkweb设置图片_ios·WKWebView\UIWebView加载HTMLString,实现图片懒加载
  15. 三星android q,三星Galaxy S11再被爆料 系统将基于Android Q
  16. 矩阵/向量/标量间相互求导
  17. TextView+Button
  18. MYSQL--表分区、查看分区
  19. Android手机不root查看/data/data/包名目录下的文件
  20. 爬虫第一课——教你学会使用requests库

热门文章

  1. 品赏第一行“Android代码“---Hello World
  2. css+div布局----典型布局基本框架
  3. 昆明-大理-丽江-泸沽湖最新自驾游记
  4. 活动.WEBGAME与SNS社区大会
  5. 阴阳师 御魂源代码分享(用了大漠插件,目前已失效,仅供学习)
  6. PowerBI工具提示的用法
  7. could not connect to any x display
  8. 软件:在Dos模拟器中安装TurboC++ 3.0
  9. APENFT FOUNDATION官宣2022艺术梦想基金主题征集
  10. 无线网卡为BCM4352(Kernel内核为bcmwl-kernel-source)的笔记本安装Ubuntu18.04后无法识别Wifi适配器的解决办法记录