Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate不退出查询缓存(不可重复读取问题)_Java_Spring_Hibernate_Ehcache_Query Cache - Fatal编程技术网

Java Hibernate不退出查询缓存(不可重复读取问题)

Java Hibernate不退出查询缓存(不可重复读取问题),java,spring,hibernate,ehcache,query-cache,Java,Spring,Hibernate,Ehcache,Query Cache,我是java/spring/hibernate新手,在经历了几年的.Net编程之后,我真的爱上了java 现在我正在使用Spring(MVC,声明性事务)和Hibernate(3.6,作为缓存提供程序-ehCache 2.5)开发web应用程序。我有一些只读和读写数据项,我想使用Hibernate第二缓存和查询缓存进行缓存 当我对只读实体使用缓存时,一切都正常。我添加了读写实体,并使用jMeter运行了性能测试。对于读写实体,我面临着不可重复读取的问题。例如,有几个并发线程读取和写入实体表 线程

我是java/spring/hibernate新手,在经历了几年的.Net编程之后,我真的爱上了java

现在我正在使用Spring(MVC,声明性事务)和Hibernate(3.6,作为缓存提供程序-ehCache 2.5)开发web应用程序。我有一些只读和读写数据项,我想使用Hibernate第二缓存和查询缓存进行缓存

当我对只读实体使用缓存时,一切都正常。我添加了读写实体,并使用jMeter运行了性能测试。对于读写实体,我面临着不可重复读取的问题。例如,有几个并发线程读取和写入实体表

线程3获取查找值:

16:34:45,304 DEBUG [http-bio-8080-exec-3] cache.StandardQueryCache:        (StandardQueryCache.java:136) - cached query results were not up to date
16:34:45,304 DEBUG [http-bio-8080-exec-3] hibernate.SQL:(SQLStatementLogger.java:111) - select virtualdev0_.virtual_device_class_id as virtual1_45_,     virtualdev0_.virtual_device_class as virtual2_45_, virtualdev0_.sitebox_id as sitebox3_45_, virtualdev0_.timestamp as timestamp45_ from virtual_device_class virtualdev0_ where     virtualdev0_.sitebox_id=?
它发现缓存不是最新的,加载实体,将它们添加到二级缓存中,具体化并返回…从这里到16:34:45826的连续过程

同时,线程9删除一个实体并更新二级缓存+时间戳:

16:34:45,799 DEBUG [http-bio-8080-exec-9] hibernate.SQL:(SQLStatementLogger.java:111) - delete from virtual_device_class where virtual_device_class_id=?
16:34:45,814 DEBUG [http-bio-8080-exec-9] cache.UpdateTimestampsCache:(UpdateTimestampsCache.java:95) - Invalidating space [virtual_device_class], timestamp: 5466792287494145
线程3继续内部管理活动,并最终将查询结果添加到查询缓存中(注意,对于线程9的删除操作,时间戳将高于timpestamp):

因此,此时删除的ID将在查询缓存中,并且查询缓存将被认为是最新的

16:34:45,852 DEBUG [http-bio-8080-exec-9] cache.UpdateTimestampsCache:(UpdateTimestampsCache.java:122) - [virtual_device_class] last update timestamp: 5466792287494145, result set timestamp: 5466792287543296
因此,当您再次尝试获取查找时,它将在查询缓存中查找,然后将开始从第二个缓存中具体化实体

16:34:45,852 DEBUG [http-bio-8080-exec-9] cache.StandardQueryCache:(StandardQueryCache.java:140) - returning cached query results
但删除的项目将不存在,所以将完成对数据库的查询

16:34:45,863 DEBUG [http-bio-8080-exec-9] loader.Loader:(Loader.java:2022) - loading entity: [com.test.models.VirtualDeviceClass#0b2f363f-fbb9-4d17-8f86-af86ebb5100c]
16:34:45,873 DEBUG [http-bio-8080-exec-9] hibernate.SQL:(SQLStatementLogger.java:111) - select virtualdev0_.virtual_device_class_id as virtual1_45_0_, virtualdev0_.virtual_device_class as virtual2_45_0_, virtualdev0_.sitebox_id as sitebox3_45_0_, virtualdev0
因为我正在使用Load方法,所以若在数据库中找不到实体,它就会抛出异常。 在我的情况下,实体很少更新,这可能会发生,这让我很担心。我对如何克服这个问题没有什么想法:

a) 将trx隔离级别设置为Repeatable Read in DB(但不要认为这会有帮助,因为添加到缓存逻辑是在从DB读取数据之后进行的) b) 在实体删除/更新时手动强制标准查询缓存退出 c) 根本不使用查询缓存(尝试将大多数db查询路由到第二个缓存)


以前有人遇到过这个问题吗?

我已经迁移到Hibernate 4,现在可以正常工作了

此问题可能与方法
SessionFactory.getQueryCache(String regionName)

16:34:45,863 DEBUG [http-bio-8080-exec-9] loader.Loader:(Loader.java:2022) - loading entity: [com.test.models.VirtualDeviceClass#0b2f363f-fbb9-4d17-8f86-af86ebb5100c]
16:34:45,873 DEBUG [http-bio-8080-exec-9] hibernate.SQL:(SQLStatementLogger.java:111) - select virtualdev0_.virtual_device_class_id as virtual1_45_0_, virtualdev0_.virtual_device_class as virtual2_45_0_, virtualdev0_.sitebox_id as sitebox3_45_0_, virtualdev0