- 浏览: 12957 次
最新评论
hibernate数据修改后不能及时更新
2010年12月22日
主要表现在新增、修改数据后,在数据列表中不能显示刚插入数据的关联对象的信息(新增插入或修改的数据主数据能显示,只有关联的数据不能显示),但刷新后能显示,再刷新可能又显示不出来了。随机的能显示或不能显示。搞不懂。
当你手动修改了数据库,Hibernate缓存中的数据就有可能是过期的。为了保证Hibernate与数据库一致,一般的
做法是在手动修改数据库之后,使用Hibernate查询数据之前,清空缓存。也就是说,你应该在执行查询前,调用
session.clear(). 参考:hibernate缓存管理
1.缓存概述
缓存(cache)在java应用程序中是一组内存中的集合示例,它保存着永久性存储源(如硬盘上的文件或数据库)中数据的备份,它的读写速度比读写硬盘的速度快。应用程序在运行时直接读写缓存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。如果缓存中存放的数据量非常大,也会用硬盘作为缓存的物理介质
缓存的作用就是降低应用程序直接读写永久性数据存储源的频率,从而增强应用的运行性能
缓存的实现不仅需要作为物理介质的硬件(内存),同时还需要用于管理缓存的并发访问和过期等策略的软件
2.缓存范围分类
缓存的范围决定了缓存的声明周期以及可以被谁访问。总共分三类
1)事务范围
事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结束.事务范围的缓存使用内存作为存储介质,一级缓存就属于事务范围.
2)应用范围(也叫进程范围)
应用程序的缓存可以被应用范围内的所有事务共享访问.缓存的生命周期依赖于应用的生命周期,只有当应用结束时,缓存的生命周期才会结束.应用范围的缓存可以使用内存或硬盘作为存储介质,二级缓存就属于应用范围.
3)集群范围
在集群环境中,缓存被一个机器或多个机器的进程共享,缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致,缓存中的数据通常采用对象的松散数据形式.
对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定回避直接访问数据库数据的速度快很多
3.缓存的并发访问策略
当多个并发的失误同时访问持久化层的缓存的相同数据时,会引发起并发问题,必须采用必要的失误隔离措施
在进程范围或集群范围的缓存,会出现并发问题,因此可以设定一下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低
1)事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。
2)读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。
3)非严格读写型:不保证缓存与数据库中数据的一致性。如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
4)只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。
Hibernate中的缓存
hibernate中提供两级缓存,第一级别是Session级别的缓存,它是属于事务范围的缓存,第二级别的缓存是SessionFactory级别的缓存,它是属于进出呢个范围或集群范围的缓存。这一级别的缓存可以进行配置和更改,并且可以进行动态的加载和卸载。Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存
一级缓存的管理:
Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,当程序调用save(),update(),saveorupdate()等方法 及调用查询接口list,filter,iterate时,如session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,
当Session关闭的时候该Session所管理的一级缓存也会立即被清除
Hibernate的一级缓存是Session所内置的,不能被卸载,也不能进行任何配置
一级缓存采用的是key-value的Map方式来实现的,在缓存实体对象时,对象的主关键字ID是Map的key,实体对象就是对应的值。所以说,一级缓存是以实体对象为单位进行存储的,在访问的时候使用的是主关键字ID
虽然,Hibernate对一级缓存使用的是自动维护的功能,没有提供任何配置功能,但是可以通过Session中所提供的方法来对一级缓存的管理进行手工干预。Session中所提供的干预方法包括以下两种
●evict() :用于将某个对象从Session的一级缓存中清除
evict()方法适用于以下二种情况:
1)不需要该对象进行同步的数据更新
2)在批量进行更新与删除时,当更新删除每一个对象后,要释对此对象所占用的内存.
●clear() :用于将一级缓存中的所有对象全部清除。
在进行大批量数据一次性更新的时候,会占用非常多的内存来缓存被更新的对象。这时就应该阶段性地调用clear()方法来清空一级缓存中的对象,控制一级缓存的大小,以避免产生内存溢出的情况。
Hibernate大批量更新时缓存的处理方法:
(假设我们user表的age有5000条大于0的记录,)
Session session =SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Itertaor users=session.find("from User u where u.age>0").itertaor();//HSL语句就不做解释了
while(user.hasNext()){
User user =(User)users.next();
user.setAge(user.getAge()+1);
//将本批插入的对象立即写入数据库并释放内存
session.flush();
session.clear();
}
tx.commit();
session.close();
用Hibernate处理大批数据时..都必须先执行5000次的update语句,然后才能更新5000个user 对象..
这样就影响到了操作上的性能....在项目当我们遇到性能与空间的问题时,,,要以性能为主..这也就是说要牺牲空间
所以程序最好跳过Hibernate API 而直接通过JDBC API来执来...
我们改一下上面的代码:
Session session=SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Connection conn =session.connection();
PreparedStatement pstmt = conn.prepareStatement("update users set age=age+1 "+"where age >0");
pstmt.executeUpdate();
tx.commit();
虽说这是通过JDBC API搞作的..但本质上还是通过Hibernater Transaction的事务这个接口来声明事务的边界的...
其实最好的解决方法就是以创建存储过程,,用底层的数据库运行..这样性能好,速度快....
我就简单的以Oracle数据库为例子.创建一个名为UserUpdate的存储过程...然后在程序中进行调用...
UserUpdate的存储过程代码:
create or replace procadure UserUpdate(u_age in number) as
begin
update users set age=age+1 where age>u_age;
end;
下面的是在程序中如何调用我们命名的存储过程
Session session =SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Connection conn=session.connection();
String str="{call UserUpdate(?)}";
CallableStatement cstmt= conn.prepareCall(str);
cstmt.setInt(1,0);
cstmt.executeUpdate();
tx.commit(); 注意.开源的MySQL中不支持存储过程的..
用JDBC API的好处是这样的..
它不用把大批量的数据事先加载到内存中,然后再进行更新与修改..所以不会消耗大量内存....
(小程序中是看不出什么差别的..当数据的记录达到一定的数据量的时候自然会发现用Hibernate API 与JDBC API的差别)
在一个就是只能一条记录进行批量更新..不像Hibernate中更新每一条的..
第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法比卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
二级缓存管理
第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。
Hibernate的二级缓存策略的一般过程如下:
1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
2) 把获得的所有数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增加数据的时候,同时更新缓存。
Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。
Hibernate的Query缓存策略的过程如下:
1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。
2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。
3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。
适合存放到二级缓存中的数据有以下四种:
1)很少被修改的数据
2)不是很重要的数据,允许偶尔并发的数据
3)不会被并发反问的数据
4)参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用。它的实例极少或从来不会被修改
对于那些常被修改的数据,如财务数据(绝对不允许出现并发)和其他应用共享的数据,这些都不能放到第二级缓存中
常用的缓存插件
Hibernate的二级缓存是一个插件,下面是几种常用的缓存插件
1)EhCache:可作为进程访问的缓存,存放的物理介质可以是内存或硬盘,对hibernate的查询缓存提供了支持
2)OSCache:可作为进程范围的缓存,存放数据的物理介质可以使内存或硬盘,体统丰富的缓存数据过期策略,hibernate的查询缓存提供了支持
3)SwarmCache:可作为集群范围内的缓存,但不支持hibernate查询缓存
4)TreeCache:可作为集群范围内的缓存,支持事务性并发访问策略,对hibernate的查询缓存提供了支持
二级缓存示例
配置一:
hibernate.cfg.xml文件中增加 配置二:
工程项目src文件下新建一个ehcache.xml文件,其内容为 配置三:
为了缓存某类的对象,其hbm文件中需添加属性例如:
配置四:
为了使用查询缓存,Query必须设置cacheable为true,query.setCacheable(true);
例如dao父类中用于hql查询的方法修改后为: /** * 执行hql语句的查询 * @param sql * @return */ public List executeQuery(String hql){ List list = new ArrayList(); Session session = HibernateSessionFactory.currentSession(); Transaction tx = null; Query query = session.createQuery(hql); query.setCacheable(true); try { tx = session.beginTransaction(); list = query.list(); tx.commit(); } catch (Exception ex) { ex.printStackTrace(); HibernateSessionFactory.rollbackTransaction(tx); } finally { HibernateSessionFactory.closeSession(); } return list; }
补充一下:当要缓存的对象处于级联关系中时。如果和他存在级联关系的对象都有属性 那么,在第一次get后该对象所处的对象图中的所有对象都会保存到hibernate的二级缓存中,在第二次get该对象时,直接从二级缓存中找到所有级联的对象;如果其中某个级联对象没有属性,则不会被保存到二级缓存中,以后每次get时仍然会执行sql去数据库中找该级联对象
发表评论
-
mmap学习笔记
2012-01-20 08:57 683mmap学习笔记 2010年12月10日 最近遇到个问题 ... -
Asio资料收集及使用点滴
2012-01-20 08:57 799Asio资料收集及使用点滴 2011年03月23日 As ... -
Asio资料收集及使用点滴
2012-01-20 08:57 713Asio资料收集及使用点滴 ... -
从solaris向linux移植应用程序的技术指导
2012-01-20 08:57 712从solaris向linux移植应用 ... -
ADO
2012-01-19 14:01 690ADO 2010年06月04日 ... -
JDK1.5 JDK1.6 各自的新特性
2012-01-19 14:01 520JDK1.5 JDK1.6 各自的新特 ... -
使用Cocos2d框架开发iPhone游戏的方法
2012-01-19 14:01 573使用Cocos2d框架开发iPhone游戏的方法 2011年 ... -
MonoTouch:用.net开发iPhone应用
2012-01-19 14:01 572MonoTouch:用.net开发iPhone ... -
什么是android模拟器?如何下载安装Android模拟器?
2012-01-19 14:01 553什么是android模拟器?如何下载安装Android模拟器? ... -
推荐一个适合菜鸟使用的小工具
2012-01-17 03:51 530推荐一个适合菜鸟使用的小工具 2011年03月24日 ... -
TOAD快速入门(中文经典)
2012-01-17 03:51 712TOAD快速入门(中文经典) ... -
ARM经典100问
2012-01-17 03:51 612ARM经典100问 2011年03月13日 第1章 体系 ... -
TIFF文件格式漏洞分析
2012-01-17 03:51 1443TIFF文件格式漏洞分析 2 ... -
STP-2保温板
2012-01-16 02:37 765STP-2保温板 2012年01月04 ... -
High compaction molding【清华大学:于震宗】
2012-01-16 02:37 650High compaction molding【清 ... -
汽车修理工中级理论复习资料
2012-01-16 02:37 812汽车修理工中级理论复习资料 2011年11月28日 汽车 ... -
计算机网络1(习题答案)
2012-01-16 02:36 819计算机网络1(习题答案) ...
相关推荐
使用springmvc+hibernate完成增删改查,数据无需创建自动生成,有问题及时沟通,希望大家共同进步。
5. 进度管理:用户可上传项目进度报告,系统自动更新项目进度信息,便于及时了解项目执行情况。 6. 统计报表:系统提供丰富的统计报表功能,帮助用户分析项目数据,为决策提供有力支持。 7. 用户管理:支持用户...
**项目名称:** 图书管理系统(基于Struts + Hibernate + Spring框架) **项目简介:** 本项目是一个基于Java Web技术的图书管理系统,采用Struts、Hibernate和Spring三大框架进行开发。该系统旨在为图书馆提供一...
功能在确认正常工作后才上传。【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来...
功能在确认正常工作后才上传。【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来...
在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。 该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下: 1. ...
功能在确认正常工作后才上传。【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来...
此外,还有嵌入式操作系统、智能操作系统等、数据集、大数据分析、人工智能、机器学习等各种项目 项目具有较高的学习借鉴价值,也适用于小白学习入门进阶。当然也可作为毕设项目、课程设计、大作业、初期项目立项...
4)库存管理:做好库存商品登记(采购回来后、出商店后),及时整理相应信息,统计好需要增购得商品 5)商品管理:动态怎删改查商品类型 6)系统管理:主要是实现对历史记录进行简要的分析,实现用户的资料更新和数据...
数据校验:Hibernate validatior 持久层框架:Mybatis 数据库:MySQL 5.7 密码加密:MD5 # 功能 全站敏感词过滤 登录验证 注册验证 文章展示 文章添加 文章删除 文章修改 # 敏感词过滤的方案 关于敏感...
2.★拥有云端版本更新通知服务器,可在后台获取官方的最新版本及每次更新的版本更新信息,及时通知用户进行升级。 3.★验证码支持短信、邮箱发送。短信模板已支持国内常用短信平台的接口,支持腾讯云短信接口。配置...
后台技术方面,我们采用Struts2负责请求转发与响应,Spring进行业务逻辑处理,Hibernate实现数据持久化。 本系统专为物流工作人员和管理员量身打造,旨在实现企业物流制度的在线化操作。系统包含四个核心模块:登录...
数据持久化:采用ORM框架如Hibernate或MyBatis来实现对象关系映射,简化数据库操作和管理。 前端技术:使用HTML、CSS和JavaScript等前端技术实现用户界面,可以选择使用Vue.js、React.js等前端框架来提升用户体验。 ...
Hibernate框架:用于实现对象关系映射(ORM),简化数据操作和管理,提高开发效率。 MySQL数据库:作为数据存储的选择,提供了稳定可靠的数据存储和管理功能。 安全性和权限控制: 对于系统的敏感操作,如用户管理...
基于Structs+Hibernate+Spring+mahout+bootstrap+junit+tomacat+mysql 实现的网上书店前后台系统, 毕业设计。所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一...
物流项目 Server 端架构: Struts2+ Spring + Spring Data(简化持久层) + JPA 接口+ Hibernate(JPA 显现) 后台管理系统 页面架构 :jQuery Easyui 框架 前端互联网系统 页面架构 :BootStrap 响….zip所有源码均...
面对如此数量巨大、来源多样、变更频繁的信息,传统的管理方法已经愈来愈不能满足现代化土地管理的需要。此外,国民经济的迅猛发展,迫切要求各级国土部门为国家提供准确的数量、质量和土地利用现状等信息。因此,...
在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。 该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下: 1. ...
特别是对于拥有大量车辆的机关企事业单位来说,车辆的管理已成为日常事务中的一项重要的工作,为了如何让管理人员及时了解每一辆车的情况,提高车辆的使用效率,减少费用支出,成为各个单位需要解决的一个难题,为了...
仓库管理信息系统所涉及的主要数据包括商品管理、进货管理、订单管理、换货管理和供应商管理,客户管理,公告通知管理下面分别分析这些数据需求。 (1)商品管理 商品管理主要是管理商品分类信息以及管理商品信息...