一、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

不要依赖hibernate的二级缓存的更多相关文章

  1. hibernate(九) 二级缓存和事务级别详讲

    序言 这算是hibernate的最后一篇文章了,下一系列会讲解Struts2的东西,然后说完Struts2,在到Spring,然后在写一个SSH如何整合的案例.之后就会在去讲SSM,在之后我自己的个人 ...

  2. hibernate的二级缓存

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

  3. 【Hibernate】 二级缓存及查询缓存

    一.Hibernate的二级缓存 1.1 类缓存区特点 缓存的是对象的散装的数据. 图一 Hibernate的二级缓存的散装数据 1.2 集合缓存区的特点: 缓存的是对象的id.需要依赖类缓冲区的配置 ...

  4. Hibernate之二级缓存

                                                            Hibernate之二级缓存 一.简介 Gaving King曾经对别人说,hibern ...

  5. SSH整合缓存之-Memcached作为hibernate的二级缓存

    Hibernate本身不提供二级缓存,所以需要使用第三方插件来作为二级缓存:本次使用memcached作为Hiberbate的二级缓存:添加步骤如下: 一.需要安装memcached服务端 1. 下载 ...

  6. Hibernate的二级缓存策略

    Hibernate的二级缓存策略的一般过程如下: 1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次 ...

  7. Java面试题:Hibernate的二级缓存与Hibernate多表查询

    我们来看两个有关Java框架之Hibernate的面试题,这是关于Hibernate的常考知识点. 1.请介绍一下Hibernate的二级缓存 解题按照以下思路来回答: (1)首先说清楚什么是缓存: ...

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

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

  9. Hibernate的二级缓存(SessionFaction的外置缓存)-----Helloword

    1. 使用 Hibernate 二级缓存的步骤: 1). 加入二级缓存插件的 jar 包及配置文件: I. 复制 \hibernate-release-4.2.4.Final\lib\optional ...

随机推荐

  1. 【转】android去掉EditView的默认焦点问题

    原文网址:http://www.111cn.net/sj/android/54680.htm 做一个输入框时发现android中EditView的默认焦点了,这种问题如果是在输入框还好,但在搜索页面或 ...

  2. Android--广播BroadcastReceiver

    前言 Android四大组件,Activity.Service.ContentProvider.BroadcastReceiver,除了BroadcastReceiver之外,其他的在之前的博客中都有 ...

  3. 【动态规划】XMU 1560 新ACM规则

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1560 题目大意: 给定n(n<=200)个任务及每个任务的耗时,问m(m< ...

  4. rails console --sandbox出现的安装错误解决方案

    rails中可以用使用console命令行来测试运行rails应用程序,但是采用源码编译安装的话可能缺少readline动态库,导致ruby无法使用这个库此时如果调用rails console(rai ...

  5. C++中的位域(bit-filed):一种节省空间的成员

    转载自:http://www.cppblog.com/suiaiguo/archive/2009/07/16/90211.html 有一种被称为位域(bit-field) 的特殊的类数据成员,它可以被 ...

  6. Android testing tools

    引言 发现一篇关于android 测试的培训,英文的,很全面. Android Testing Training: http://www.vogella.com/training/android/an ...

  7. K - Rochambeau - poj2912(类似食物链)

    一群小孩玩一个简单石头布布游戏,这些小孩会分成三组(组内可能没有人)+一个自由人(比翻译成裁判合理多了),同一组的小孩只会出同一种手势(不会变的),不过裁判可以出任意的手势,这些小孩能就会相互猜拳玩, ...

  8. iOS利用Runtime自定义控制器POP手势动画

    前言 苹果在iOS 7以后给导航控制器增加了一个Pop的手势,只要手指在屏幕边缘滑动,当前的控制器的视图就会跟随你的手指移动,当用户松手后,系统会判断手指拖动出来的大小来决定是否要执行控制器的Pop操 ...

  9. python成长笔记

    正则表达式 1.    择一匹配:管道符号(|),表示“从多个模式中选择其一”.例:at|home à at.home 2.    点号匹配除了换行符以外的任何字符 3.    边界匹配:\b匹配一个 ...

  10. 多态 JAVA

    多态(Java)   一.多态 1.什么是多态? 不同的对象对于同一个操作,做出的响应不同 具有表现多种形态的能力的特征 2.使用多态的优点 : 为了实现统一调用 二.子类到父类的转换(向上转型) ① ...