`

Hibernate的缓存讨论

阅读更多

一般系统中有三种情况会绕开hibernate执行数据库操作:

1、多个应用系统同时访问一个数据库

    此种情况使用hibernate二级缓存会不可避免的造成数据不一致的问题,

    此时要进行详细的设计。比如在设计上避免对同一数据表的同时的写入操作,

    使用数据库各种级别的锁定机制等。


2、动态表相关

    所谓“动态表”是指在系统运行时根据用户的操作系统自动建立的数据表。

    比如“自定义表单”等属于用户自定义扩展开发性质的功能模块,因为此时数据表是运行时建立的,所以不能进行hibernate的映射。因此对它的操作只能是绕开hibernate的直接数据库JDBC操作。

      如果此时动态表中的数据没有设计缓存,就不存在数据不一致的问题。

    如果此时自行设计了缓存机制,则调用自己的缓存同步方法即可。


3、使用sql对hibernate持久化对象表进行批量删除时

      此时执行批量删除后,缓存中会存在已被删除的数据。

分析:

    当执行了第3条(sql批量删除)后,后续的查询只可能是以下三种方式:

a. session.find()方法:

根据前面的总结,find方法不会查询二级缓存的数据,而是直接查询数据库。

所以不存在数据有效性的问题。

b. 调用iterate方法执行条件查询时:

根据iterate查询方法的执行方式,其每次都会到数据库中查询满足条件的id值,然后再根据此id 到缓存中获取数据,当缓存中没有此id的数据才会执行数据库查询;

如果此记录已被sql直接删除,则iterate在执行id查询时不会将此id查询出来。所以,即便缓存中有此条记录也不会被客户获得,也就不存在不一致的情况。(此情况经过测试验证)
c. 用get或load方法按id执行查询:
客观上此时会查询得到已过期的数据。但是又因为系统中执行sql批量删除一般是

针对中间关联数据表,对于

中间关联表的查询一般都是采用条件查询 ,按id来查询某一条关联关系的几率很低,所以此问题也不存在!


如果某个值对象确实需要按id查询一条关联关系,同时又因为数据量大使用 了sql执行批量删除。当满足此两个条件时,为了保证按id 的查询得到正确的结果,可以使用手动清楚二级缓存中此对象的数据的方法!!

(此种情况出现的可能性较小)

 


 建议
1、建议不要使用sql直接执行数据持久化对象的数据的更新,但是可以执行 批量删除。(系统中需要批量更新的地方也较少)


2、如果必须使用sql执行数据的更新,必须清空此对象的缓存数据。调用

SessionFactory.evict(class)

SessionFactory.evict(class,id)

等方法。


3、在批量删除数据量不大的时候可以直接采用hibernate的批量删除,这样就不存在绕开hibernate执行sql产生的缓存数据一致性的问题。


4、不推荐采用hibernate的批量删除方法来删除大批量的记录数据。

原因是hibernate的批量删除会执行1条查询语句外加 满足条件的n条删除语句。而不是一次执行一条条件删除语句!!

当待删除的数据很多时会有很大的性能瓶颈!!!如果批量删除数据量较大,比如超过50条,可以采用JDBC直接删除。这样作的好处是只执行一条sql删除语句,性能会有很大的改善。同时,缓存数据同步的问题,可以采用 hibernate清除二级缓存中的相关数据的方法。

调用 SessionFactory.evict(class) ;SessionFactory.evict(class,id)等方法。


所以说,对于一般的应用系统开发而言(不涉及到集群,分布式数据同步问题等),因为只在中间关联表执行批量删除时调用了sql执行,同时中间关联表一般是执行条件查询不太可能执行按id查询。所以,此时可以直接执行sql删除,甚至不需要调用缓存的清除方法。这样做不会导致以后配置了二级缓存引起数据有效性的问题。
退一步说,即使以后真的调用了按id查询中间表对象的方法,也可以通过调用清除缓存的方法来解决。


具体的配置方法
根据我了解的很多hibernate的使用者在调用其相应方法时都迷信的相信“hibernate会自行为我们处理性能的问题”,或者“hibernate会自动为我们的所有操作调用缓存”,实际的情况是hibernate虽然为我们提供了很好的缓存机制和扩展缓存框架的支持,但是必须经过正确的调用其才有可能发挥作用!!所以造成很多使用hibernate的系统的性能问题,实际上并不是hibernate不行或者不好,而是因为使用者没有正确的了解其使用方法造成的。相反,如果配置得当hibernate的性能表现会让你有相当“惊喜的”发现。下面我讲解具体的配置方法.

ibernate提供了二级缓存的接口:
net.sf.hibernate.cache.Provider,
同时提供了一个默认的 实现net.sf.hibernate.cache.HashtableCacheProvider,
也可以配置 其他的实现 比如ehcache,jbosscache等。

具体的配置位置位于hibernate.cfg.xml文件中
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</property>

很多的hibernate使用者在 配置到 这一步 就以为 完事了,
注意:其实光这样配,根本 就没有使用hibernate的二级缓存。同时因为他们在使用hibernate时大多时候是马上关闭session,所以,一级缓存也没有起到任何作用。结果就是没有使用任何缓存,所有的hibernate操作都是直接操作的数据库!!性能可以想见。

正确的办法是除了以上的配置外还应该配置每一个vo对象的具体缓存策略,在影射文件中配置。例如:

<hibernate-mapping>
<class name="com.sobey.sbm.model.entitySystem.vo.DataTypeVO" table="dcm_datatype">
<cache usage="read-write"/>
<id name="id" column="TYPEID" type="java.lang.Long">
<generator class="sequence"/>
</id>

<property name="name" column="NAME" type="java.lang.String"/>
<property name="dbType" column="DBTYPE" type="java.lang.String"/>
</class>
</hibernate-mapping>


关键就是这个<cache usage="read-write"/>,其有几个选择
read-only,read-write,transactional,等
然后在执行查询时 注意了 ,如果是条件查询,或者返回所有结果的查询,此时session.find()方法 不会获取缓存中的数据。只有调用query.iterate()方法时才会调缓存的数据。

同时 get 和 load方法 是都会查询缓存中的数据 .

 

分享到:
评论

相关推荐

    Bug管理系统 struts2+sping2.5+hibernate3(1-2)

    主要展示技术包括:三层架构 freemarker模版 面向切面编程 邮件发送 定时任务 缓存管理 运行环境: 1 TOMCAT 5.5及以上版本. 2 JDK5.0及以上版本. 3 ECLIPSE3.2 及以上版本. 4 MySQL5.0 注意事项: 1 TOMCAT安装...

    Bug管理系统 struts2+sping2.5+hibernate3(2-2)

    主要展示技术包括:三层架构 freemarker模版 面向切面编程 邮件发送 定时任务 缓存管理 运行环境: 1 TOMCAT 5.5及以上版本. 2 JDK5.0及以上版本. 3 ECLIPSE3.2 及以上版本. 4 MySQL5.0 注意事项: 1 TOMCAT安装...

    OSX-RAMDisk:OS-X中用于IntelliJ的RAM磁盘创建器,Google Chrome和其他应用程序进行缓存以使其运行

    该应用程序将在OS-X中创建具有指定大小的,以将应用程序缓存存储在RAM中,这称为SSD优化-减少磁盘IO或使使用IntelliJ的网络浏览和编程更加有趣。 支持的应用程序(您可以添加您的应用程序): 苹果浏览器 的iTunes...

    Android数据库应用编程——为企业开发数据驱动Android应用

    ◆ 重点讨论为基于REST的应用程序创建和使用简单数据库以便缓存和同步结果 ◆ 介绍内容提供器、REST、并发和网络 ◆ 详解使用Hibernate创建REST风格的Web服务以及将其连接到Android ◆ 通过避免在Internet上执行CRUD...

    Spring面试题

    1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存 2. 二级缓存: a) 应用及缓存 b) 分布式缓存 条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非 关键...

    2个开源的BLOG

    使包括日记、照片、讨论均可使用标签 支持多种友情链接包括:WEB、WAP、RSS、站内等 全功能WAP支持 允许设置多个超级管理员对各个空间数据进行管理 技术 升级组件Hibernate-&gt;3.1.3, Strus-&gt;...

    iBATIS实战

    书中既详实地介绍了iBATIS的设计理念和基础知识,也讨论了动态SQL、高速缓存、DAD框架等高级主题,还讲解了iBATIS在实际开发中的应用。书的最后给出了一个设计优雅、层次清晰的示例程序JGameStore,该示例涵盖全书的...

    springboot信息化在线教学平台的设计与实现.zip

    技术栈方面,除了Spring Boot作为主要后端框架外,该项目可能还使用了如MyBatis或Hibernate的ORM框架,MySQL或PostgreSQL作为数据库,Redis用于缓存,以及前端技术如AngularJS、React或Vue.js等。该资源包适合软件...

    蝙蝠在线考试系统 2.2.8.rar

    本系统采用JAVA技术构建,中间层与数据访问层采用了SPRING技术和HIBERNATE技术,数据缓冲、大并发数据访问支持能力卓越,这种能力在多用户同时考试生成试卷和同时提交试卷并计算得分时非常重要,出现卡死的可能性较...

    JAVA毕业设计之基于springboot的疾病防控综合系统的设计与实现(springboot+mysql)完整源码.zip

    Hibernate Validator:用于后端数据的校验。 Redis:可能用于缓存数据,提高系统响应速度。 Swagger:用于生成API文档,方便开发者了解和测试API接口。 功能方面,系统可能包括以下几个核心模块: 用户管理:包括...

    SpringBoot项目校园周边美食探索及分享平台的设计与实现.zip

    技术实现方面,后端使用SpringBoot来简化开发流程,SpringMVC处理Web请求和响应,MyBatis或Hibernate作为ORM工具与数据库交互,保证数据的一致性和安全性。前端可能采用Angular、React或Vue.js等现代JavaScript框架...

    JspRun!社区论坛系统 v6.0 bulid 090423 GBK 源码版.rar

    2006年7月 CNNIC 发布的最新统计表明,43.2% 的中国网民经常使用论坛/BBS/讨论组,论坛社区应用首次超过即时通讯 IM ,成为仅次于收发Email的互联网基本应用。 JspRun!是飞速创想(北京)科技有限公司推出的一套通用的...

    JspRun!社区论坛系统 v6.0 bulid 090424 GBK 安装版.rar

    2006年7月 CNNIC 发布的最新统计表明,43.2% 的中国网民经常使用论坛/BBS/讨论组,论坛社区应用首次超过即时通讯 IM ,成为仅次于收发Email的互联网基本应用。 JspRun!是飞速创想(北京)科技有限公司推出的一套通用的...

Global site tag (gtag.js) - Google Analytics