主要表现在新增、修改数据后,在数据列表中不能显示刚插入数据的关联对象的信息(新增插入或修改的数据主数据能显示,只有关联的数据不能显示),但刷新后能显示,再刷新可能又显示不出来了。随机的能显示或不能显示。搞不懂。
当你手动修改了数据库,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所内置的,不能被卸载,也不能进行任何配置