2012-04-18 2 views
3

나는 java/spring/hibernate에 익숙하지 않고 .net 프로그래밍의 몇 년 후에 java에서 정말 사랑에 빠졌다.Hibernate는 질의 캐시를 제거하지 않는다. (반복 불가능한 읽기 문제)

이제 Spring (MVC, 선언적 트랜잭션)과 Hibernate (3.6, 캐시 제공자 - ehCache 2.5)를 사용하는 웹 응용 프로그램에서 작업하고 있습니다. 나는 Hibernate second cache와 query cache를 사용하여 캐시하고 싶은 읽기 전용 및 읽기 - 쓰기 enitties를 가지고있다.

읽기 전용 엔티티에 캐싱을 사용하면 모든 것이 올바르게 수행되었습니다. 읽기 - 쓰기 엔티티를 추가하고 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 : 45,826

한편 스레드 (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,826 DEBUG [http-bio-8080-exec-3] cache.StandardQueryCache:(StandardQueryCache.java:96) - caching query results in region: org.hibernate.cache.StandardQueryCache; timestamp=5466792287543296 

및 쿼리 캐시합니다 최신이라고 간주 될 수있다.

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 

하지만 삭제 된 항목이 없으므로 db에 대한 쿼리가 수행됩니다.

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 메서드를 사용하므로 db에 엔터티가 없으면 예외를 throw합니다. 내 경우에는 엔터티가 거의 업데이트되지 않을 수도 있고 그것이 걱정 될 수도 있습니다. 나는이 문제를 극복하려고 시도하는 방법을 거의 가지고 있지 않다 :

a) trx 격리 수준을 DB에서 반복 가능 읽기로 설정한다. (그러나 db에서 데이터를 읽은 후 캐시 논리에 추가하기 때문에 도움이된다고 생각하지 않는다.) B) 수동() DB 쿼리의 대부분이 두 번째 캐시를 사용하는 경로를하려고 전혀 쿼리 캐시를 사용하지 않는)/업데이트 C를 삭제 엔티티에 퇴거 표준 쿼리 캐시를 강제

전에이 문제를 가진 사람의 얼굴을 했 ?

답변

1

나는 최대 절전 모드 4로 이주했으며 지금은 정상적으로 작동한다. 이 문제는 동기 블록에 관련되었을 수

메소드 SessionFactory.getQueryCache(String regionName)

link to hibernate issue

제거되고