`

Hibernate中的缓存机制和锁

阅读更多
一、Hibernate中的悲观锁(pessimistic)和乐观锁(optimistic)

1.hibernate悲观锁

1)hibernate自动设置悲观锁定

当使用Hibernate更新或者插入一行记录的时候,锁定级别自动设置为LockMode.WRITE。

当Hibernate在“可重复读”或者是“序列化”数据库隔离级别下读取数据的时候,锁定模式自动设置为LockMode.READ。这种模式也可以通过用户显式指定进行设置.

当事务结束,所有对象脱离锁定模式.

2)显式的用户指定悲观锁定方式

调用 Session.load()的时候指定锁定模式(LockMode)。

调用Session.lock()。

调用Query.setLockMode()。

当多个线程并发修改某条数据即对应的实体对象时,如果此时该对象正在被其中一个线程修改,那么,其他线程挂起,一直等待线程提交完成

如果在UPGRADE或者UPGRADE_NOWAIT锁定模式下调用Session.load(),并且要读取的对象尚未被session载入过,那么hibernate会发出sql语句载入对象。如果为一个session调用load()方法查询某个对象时,该对象已经在另一个较少限制的锁定模式下被载入了,那么Hibernate就对该对象调用lock()方法,即该对象被锁定。

session.load(Account.class, 1, LockMode.UPGRADE);

2.hibernate乐观锁

大多数基于数据版本记录机制(version)实现。一般是在数据库表中加入一个version字段

读取数据时,将版本号一同读出,之后更新数据时,版本号加1,如果提交的数据小于或者等于数据库表中的版本号,则认为数据是过时的,否则给予更新。

配置文件需要做如下改动,在<class>标签中加上optimistic-lock="version",在<class>内部<id>标签的下面定义<version ></version>
hibernate会自动维护version的版本号码,如果多个并发同时修改数据,先提交的会成功.
具体配置如下:
<class name="Account" table="tbl_account">
<id name="id" column="id">
  <generator class="native"></generator>
</id>
<version name="version"></version>
<property name="name"></property>
<property name="balance"></property>

</class>

二、hibernate一级缓存

一级缓存生命周期很短和session的生命周期一致,一级缓存也叫session级缓存或事务级缓存

每个Session有自己的缓存,一级缓存只针对单个session,其他的session里面的缓存不会被查询到

哪些方法支持一级缓存:

* get()

* load()

* iterate(查询实体对象时),iterate查询普通属性,一级缓存不会缓存

Student student = (Student)session.createQuery("from Student s where s.id=1").iterate().next();  

System.out.println("student.name=" + student.getName()); 

iterate会去数据库查ID,然后看这个ID的对象在一级缓存里面是否存在,如果存在的话就不会去数据库里面查

*list只会把对象放到缓存中,但不会从缓存中取对象

在同一个session中先save,在发出load查询save过的数据,不会查询数据库,sava支持缓存。



如何管理一级缓存:

* session.clear()

* session.evict()

如何避免一次性大量的实体数据入库导致内存溢出

* 分批导入强制先flush 然后再clear



for (int i=0; i<1000; i++) {  

    Student student = new Student();  

    student.setName("s_" + i);  

    session.save(student);  

    //每10条数据就强制session将数据持久化  

    //同时清除缓存,避免大量数据造成内存溢出  

    if ( i % 10 == 0) {  

        //flush是使数据持久化  

        session.flush();  

        //清空缓存clear,evict  

        //session.evict(Object object)  

        session.clear();  

    }  



如果数据量特别大,考虑JDBC实现,如果JDBC也不能满足要求,可以考虑采用数据库本身的特定导入工具



三、hibernate二级缓存

二级缓存也称进程级的缓存,同时也称作sessionFactory级的缓存,二级缓存可以被同一个SessionFactory创建的所有session共享

二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存

二级缓存的配置和使用:

默认情况下,Hibernate使用EHCache进行JVM级别的缓存

* 将ehcache.xml文件拷贝到src目录下,部分参数介绍

<ehcache> 

    <diskStore path="java.io.tmpdir"/> 

    <defaultCache 

        maxElementsInMemory="10000"  <!-- 缓存最大的对象数目 -->  

        eternal="false"  <!-- 缓存是否持久,不持久就会在规定时间内失效 -->   

        timeToIdleSeconds="120" <!-- 当缓存闲置n秒后销毁 -->  

        timeToLiveSeconds="120" <!-- 当缓存存活n秒后销毁-->   

        overflowToDisk="true"   <!-- 是否保存到磁盘,当对象达到规定的最大数目时-->  

        /> 

</ehcache> 

* 开启二级缓存,修改hibernate.cfg.xml文件,加入如下配置

  <property name="hibernate.cache.use_second_level_cache">true</property>

* 指定缓存产品提供商 修改hibernate.cfg.xml文件

  <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

* 知道你过哪些实体类 使用二级缓存(两种方法)

* 在映射文件中采用<cache>标签,在class标签下配置<cache usage="read-only"/>必须配置到<id>标签的前面

* 在hiberanate.cfg.xml文件中,采用<class-cache>标签

<class-cache usage="read-only"/>

如何管理二级缓存:

* sessionFactory.evict(Student.class)从缓存中移除所有的Student类型的对象

* sessionFactory.evict(Student.class,id)从缓存中移除指定id的Student 类型的对象

二级缓存是缓存实体对象的

* 了解一级缓存和二级缓存的交互

CacheMode.NORMAL - 从二级缓存中读、写数据。默认

CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。

CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。



四、Hibernate查询缓存

查询缓存是针对普通属性结果集的缓存,对实体对象的结果集只缓存id(其ID不是对象的真正ID,它与查询的条件相关即where后的条件相关,不同的查询条件,其缓存的id也不一样)

查询缓存的生命周期,当前关联的表发生修改,或是查询条件改变时,那么查询缓存生命周期结束,它不受一级缓存和二级缓存 的生命周期的影响

查询缓存的配置和使用

* 在hiberante.cfg.xml文件中启用查询缓存,如:

  <property name="hibernate.cache.use_query_cache">true</property>

* 在程序中必须手动启用查询缓存,如:

  query.setCacheable(true);

启用了查询缓存query.list()就可以从查询缓存中取数据了,不用每次都重新发sql查询数据库了
分享到:
评论

相关推荐

    Hibernate框架 jar 架包 开发详解

    Hibernate 简介 Hibernate 开发流程 Hibernate 配置文件 Hibernate 核心接口和类 Hibernate ORM映射 HQL Hibernate 懒加载机制与抓取策略 Hibernate 缓存 Hibernate 锁机制

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    涵盖了90%以上的面试题

    hashmap的底层原理 hashmap产生死锁的原因 hashmap的容量为什么...MySQL 中的行级锁、表级锁和页级锁 java中的死锁 公平锁和非公平锁 锁的总结 锁的优化 .......... 还有好多,不想写了,太多了,都是题主呕心沥血总结的

    低清版 大型门户网站是这样炼成的.pdf

    5.8 hibernate的缓存机制 332 5.8.1 hibernate的缓存分类 332 5.8.2 hibernate的缓存范围 332 5.8.3 hibernate的缓存管理 333 5.8.4 hibernate二级缓存的并发访问策略 333 5.8.5 hibernate的二级缓存配置 334 ...

    Java常见面试题208道.docx

    121.说一下 hibernate 的缓存机制? 122.hibernate 对象有哪些状态? 123.在 hibernate 中 getCurrentSession 和 openSession 的区别是什么? 124.hibernate 实体类必须要有无参构造函数吗?为什么? 十三、Mybatis ...

    jdbc基础和参考

    脏检查:自动对缓存中的数据进行检查,并且选择在合适的时机和数据库之间进行交互,以保持数据的一致性 延迟加载:从数据库中还原对象的时候,不会立即对对象进行初始化,而是等到用到的时候才会进行初始化 Core:...

    面试题问题合集.docx

    9.mybatis和hibernate主要的区别?mybatis框架介绍? 16.hashmap原理?底层怎么实现的?如何取得key值?用代码怎么写? 17. 多进程与多线程编程的区别?多线程的实际运行环境?怎么运用? 21.redis数据怎么缓存的...

    Java面试宝典2020修订版V1.0.1.doc

    14、Hibernate中load和get的区别? 92 15、Hibernate的工作原理? 92 16、hibernate优缺点? 92 17、Hibernate是如何延迟加载的? 93 18、如果优化Hibernate? 93 19、什么是ORM? 94 20、Hibernate的主键生成策略? ...

    涵盖了 Java 基础、集合、源码、并发、虚拟机、框架、数据库、网络编程、设计模式、新特性和数据结构等多个知识领域的面试突击

    数据库和缓存:SQL优化、索引、Redis、Memcached等 分布式系统:负载均衡、集群、分布式事务、分布式锁等 使用人群: Java初/中级工程师,准备面试、,巩固和提升Java技能 -高级工程师和架构师,掌握核心原理,解决复杂问题...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ Java面试题41.jQuery中Ajax和原生js实现Ajax的关系.mp4 │ Java面试题42.简单说一下html5.mp4 │ Java面试题43.简单说一下css3.mp4 │ Java面试题44.bootstrap的是什么.mp4 │ Java面试题45.什么是框架.mp4 │ ...

    Spring.3.x企业应用开发实战(完整版).part2

    17.4.5 使用Hibernate二级缓存 17.5 对持久层进行测试 17.5.1 配置Unitils测试环境 17.5.2 准备测试数据库及测试数据 17.5.3 编写DAO测试基类 17.5.4 编写BoardDao测试用例 17.6 服务层开发 17.6.1 UserService的...

    Spring3.x企业应用开发实战(完整版) part1

    17.4.5 使用Hibernate二级缓存 17.5 对持久层进行测试 17.5.1 配置Unitils测试环境 17.5.2 准备测试数据库及测试数据 17.5.3 编写DAO测试基类 17.5.4 编写BoardDao测试用例 17.6 服务层开发 17.6.1 UserService的...

    Java学习笔记-个人整理的

    {2.8}框架中移动的小球}{59}{section.2.8} {2.9}抽象与接口}{59}{section.2.9} {2.10}访问控制}{60}{section.2.10} {2.10.1}类的属性}{60}{subsection.2.10.1} {2.10.2}类的方法}{61}{subsection.2.10.2} {...

    learning-notes:学习一些东西

    哨兵模式和Redis-Cluster集群)2.Redis内存回收机制3.Redis笔记4.Redis Cluster原理5.Redis锁6.Redis分库分表分库分表网络1.https原理2.TCP与UDPMyBatis一级与二级缓存hibernate一级与二级缓存Spring1.循环依赖MySQL...

Global site tag (gtag.js) - Google Analytics