2010-12-17 8 views
6

私はEhCacheのデコレータSelfPopulatingCacheを使用していますが、キャッシュが新しいエントリを読み込もうとしましたが、存在しません(データベースに存在しません)。したがって、キャッシュはnullの値をキャッシュに入れ、そのキーの他の取得をブロック解除しますが、次のスレッドはキャッシュから「ヌル」を受け取ったため同じデータベース呼び出しを行います。これはエントリがロードされる必要があると考えていることを意味します。データはどこにも存在しないため、実際にはnullですが。私は何かが間違っているように感じる。Ehcache - データが存在しないときにSelfPopulatingCacheを使用する

(擬似コード)

Value v = cache.get(key); // multiple threads will block here 
if (v == null) 
    cache.put(key, getValueFromDB()); // this might put a null value 

私の現在のソリューションはnullで入れないことではなく、プレースホルダObjectを入れて、それをチェックすることです。

Value v = cache.get(key); 
if (v == null) 
    cache.put(key, getValueFromDB()); 
else if (v == NOENTRYOBJECT) 
    return null; 
else 
    return v; 

考えられますか?

+0

あなたの疑似コードが 'SelfPopulatingCache'にどのように関係しているかはっきりしません。どのようにそれを使用していますか? – skaffman

+0

cache = SelfPopulatingCache(またはBlockingCache)...かなり明確だったと思った – Gandalf

答えて

3

同様のことをします。ここでは、要求されたキーが有効な項目に対応していない場合は、キャッシュにBoolean.FALSEと入力します。基本的には、呼び出したコードに、要求されたキーがどのデータとも一致しないことを伝えます。有効なデータに対応していないことを検出するためには、そのキーの最初の要求でdbを1回呼び出す必要がありますが、その後の呼び出しではdbルックアップは使用できません。もちろん、そのキーのデータがDBに入力された場合は、そのキャッシュエントリを無効にする必要があります(そうでなければ、実際のデータが利用可能であってもBoolean.FALSEを返します)。

私の応答がそれほど助けになるかどうかはわかりませんが(それは別のアプローチではありません)、あなたのアプローチでは一人ではないことを少なくとも検証します。

私はこれがEHCacheのSelfPopulatingCacheに固有のものではないと考えています。

1

典型的なパターンは、アイテムのKEYむしろVALUEよりも、全くキャッシュに存在する場合、データベースを再確認するものではありません。

パターンは、ehcacheドキュメントのCaching Empty Valuesに記載されています。

通常、常にではないが、getput(id, value)がこれまでに以前に呼び出された場合、そのget(id)は値がnullの場合でも、nullにはならないだろう、Element返します。

これはキャッシュの実装に依存することに注意してください。 ehcacheのドキュメントは、常に動作するはずであることを示唆しているようですが、BlockingCache(およびその子孫)does NOT allow putting null values into the cacheです。ベースのehcache Cacheオブジェクトでは、多くの例やカスタム実装と同様に、キャッシュにnull値を格納できます。

あなたがすでに持っている解決策(プレースホルダー値オブジェクト)は、動作し、ehcacheベースCacheクラスとドキュメントと同じ結果を達成するはずです。

+0

実際はそうではありません - BlockingCacheとput(..)メソッドのコードを見ると、value == nullの場合、キャッシュ。だからput(id、null)は効果的にキャッシュに何も入れません。次のidはnullを返します。 – Gandalf

+0

Hmmm。私はコードを見ていないので、それが決定的な情報源になるでしょう。しかし、それはEhcacheの文書と完全に矛盾しているようです。私はnull値をキャッシュすることができない場合(それを明示的に指示しています)、「空の値をキャッシュする」例がどのように機能するかはわかりません。私はチャンスを得たときにコードを詳しく見ていきますが、私は過去にそれをやっていることを思い出しています。それはうまく働いています(あなたにはあいまいな想いはありません。 /否定)。 –

+0

私はそれが何であるかを見ます。私のキャッシュ実装は、組み込みのEhcacheインプリメントやもちろんSelfPopulatingCacheを使用していません。私のputメソッドは、putNullInCacheという名前のキャッシュ実装で設定されたブール値を使用します。デフォルトはtrueであるため、nullを格納することができます。だから、キャッシュのインプリメンテーションに依存し、あなたはSelfPopulatingCacheについて完全に正しいです。私はチャンスを取ったときに誰かのために将来の参照のために私の "答え"を更新しますが、それは間違いです。とにかく、あなたがやっていることは、とにかく同じネットエフェクトを持っていると思います。 –

0

CacheElementFactoryを調べる必要があると思います。私はキャッシュにロード情報を要求するために私が取り組んでいたプロジェクトのために春に実装しました。キャッシュミスがあった場合、データベースからロードしようとしました。私はこれについて何をやったのかを覚えていません。不幸にも、不足しているキーを要求したパスごとにデータベースにリクエストが行われると思います。

関連する問題