8

プロジェクトではhibernate4ehcacheを使用しています。私たちは主に不変オブジェクトに取り組んでいるため、キャッシングは私たちのアプリケーションにうまく適合する機能です。クエリ キャッシュを有効にしようとしたときに、次の問題が発生しました。

次のエンティティがあると仮定します。

@Entity 
@Table(name = "DOGS")
@Immutable 
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
class Dog {
  @Id @Column
  Long id;
  @Column
  String name;
}

そしてクエリ:

Criteria criteria = session.createCriteria(Dog.class);
criteria.add(Restrictions.in("id", ids));
criteria.setCacheable(true);

クエリ キャッシュの timeToLive は、Dog の timeToLive の約 3/4 に設定されています。シナリオは次のとおりです(間違った仮定をした場合は修正してください):

  1. クエリが初めて呼び出されると (キャッシュが空の場合)、クエリが実行され、返された Dog インスタンスが第 2 レベルのキャッシュに格納されます。また、Dog ID はクエリ キャッシュに格納されます。
  2. クエリが 2 回目に呼び出されると (Dog ID はクエリ キャッシュにあり、Dog オブジェクトは L2 キャッシュにあります)、すべて正常に動作します。クエリ キャッシュは ID を返し、Dog は L2 からフェッチされます。
  3. クエリ キャッシュの有効期限が切れると (ただし、L2 キャッシュは引き続き有効です)、クエリが再実行され、Dog ID がキャッシュされます。
  4. これで、Dog オブジェクトの L2 キャッシュが期限切れになり、すべてのオブジェクトがキャッシュから削除されます。クエリ キャッシュにはまだ ID がキャッシュされているため、hibernate は Dog オブジェクトを 1 つずつフェッチしますが、これには時間がかかります。

3番目のポイントは私を悩ませています。クエリ キャッシュが無効になり、データベースで再実行され、Dog オブジェクトがフェッチされましたが、L2 キャッシュで Dog オブジェクトが更新されませんでした。クエリはクエリ キャッシュ内の犬の ID のみを更新し、L2 キャッシュは更新しなかったようです。

クエリで L2 キャッシュも強制的に更新する方法はありますか? おそらく、このシナリオは別の方法で処理されるのでしょうか?

4

3 に答える 3

2

第 2 レベルのキャッシュは、キャッシュされるように指定したオブジェクト/Pojo 用です。 を参照してください。ただし、クエリ キャッシュは特定のクエリに対して作成されます。したがって、両方が無関係であり、クエリ キャッシュが更新されたときに 2 次キャッシュが更新されないのは当然のことです。そのため、両者には異なる構成があります。Hibernate のドキュメントを参照するか、このリンクまたはこのリンクを参照すると、理解に役立つ場合があります。

于 2013-07-25T12:04:25.603 に答える
1

私はこれを試し、過去に私のために働いてL2キャッシュをきれいにしました

//clear the cache entity
sf.getCache().evictEntity(Dog.class,12345); //Entity with 12345 id

//or clear a collection 
sf.getCache().evictCollection("com.package.Dog.getCol",12345); //Collections
//Note: the collection contains the name of the fully qualified class.

//then, run the query

それが役に立てば幸い

于 2013-07-25T09:58:52.627 に答える