私はjava/spring/hibernateの新機能であり、数年の.NETプログラミングを経て本当に魅力的です。Hibernateはクエリキャッシュを退去させません(反復可能でない読み取りの問題)
私はSpring(MVC、宣言的トランザクション)とHibernate(3.6、cache provier - ehCache 2.5)を使ってWebアプリケーションを開発しています。私は、Hibernateの第2キャッシュとクエリキャッシュを使用してキャッシュしたい読取り専用と読取り/書込み専用の機能をいくつか持っています。
読み取り専用エンティティのためにキャッシュを使用したときはすべて問題ありませんでした。読み書きエンティティを追加し、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よりも高くなる気づく):
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
したがって、この時点では、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
削除されたアイテムはそこには存在しないので、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に見つからない場合は例外をスローします。私のケースでは エンティティはめったに更新されない可能性があります。私はいくつかのアイデアをこの問題を克服しようとしている:
a)反復可能なDBに読み取りを設定します(しかし、キャッシュロジックへの追加はdb ) b)はすべて手動でクエリキャッシュを使用しない)/更新 Cを削除するエンティティに立ち退かせるために、標準クエリキャッシュを強制(第2キャッシュを使用するルートにDBクエリのほとんどを試してみてください)
誰もが前に、この問題に直面しました?