Hibernateの1次および2次レベルのキャッシュとは何ですか?


245

Hibernateの第1レベルと第2レベルのキャッシングについて簡単に説明できますか?

回答:


300

1.1)一次キャッシュ

1次キャッシュは常にSessionオブジェクトに関連付けられます。Hibernateはデフォルトでこのキャッシュを使用します。ここでは、1つのトランザクションを次々に処理します。つまり、1つのトランザクションを何度も処理しないということです。主に、特定のトランザクション内で生成する必要があるSQLクエリの数を減らします。これは、トランザクションで行われたすべての変更の後に更新するのではなく、トランザクションの最後にのみトランザクションを更新します。

1.2)2次キャッシュ

2次キャッシュは常にセッションファクトリオブジェクトに関連付けられます。トランザクションの実行中、その間にオブジェクトがセッションファクトリレベルで読み込まれるため、これらのオブジェクトは、シングルユーザーにバインドされずに、アプリケーション全体で利用できます。オブジェクトは既にキャッシュに読み込まれているため、クエリによってオブジェクトが返されるときはいつでも、データベーストランザクションを実行する必要はありません。このようにして、2次キャッシュが機能します。ここではクエリレベルのキャッシュも使用できます。

引用元:http : //javabeat.net/introduction-to-hibernate-caching/


38
1番目のレベルのキャッシュをセッションオブジェクトに、2番目のレベルのキャッシュをセッションファクトリオブジェクトにマッピングするための+1。読み続ける必要はありません。
Mahes

1
1次キャッシュ。ほとんどの場合それは必要ありませんが、それを取り除くオプションはありません。しかし、あなたは...それをすべての時間を考える必要があります
SES

6
@sesほとんどの場合、1次キャッシュが必要です。そうしないと、N + 1クエリのような非常に悪いパフォーマンスの問題が発生したり、熱心なプリフェッチキャッシュがなかったり、属性にアクセスするたびにクエリが1回発生したりします。
デニスC

通常、私たちは非常に短い期間セッションを使用します(そして、非常に身体がそれを推奨します)/存続期間の短いセッション:その期間はそのキャッシュを使用しません。セッションの寿命が長い場合は、データを(たとえば、フォームを編集するときに)セッションから切り離します。これは、存続期間の長いセッションの複雑なリクエストアフターリクエストを作成するときにquery-session-apiを使用しようとする場合の1つのシナリオでのみ必要となるようです。
2013

1
@DennisCheung:リンクが切れています。親切にjavabeat.net/introduction-to-hibernate-cachingで
NewUser

118

Streamline Logicブログには、第1レベルのキャッシングに関するかなり良い説明があります。

基本的に、第1レベルのキャッシュはセッションごとに行われ、第2レベルのキャッシュは複数のセッション間で共有できます。


20
それはすぐそこにある単純な言葉です、なぜ彼らがそれを説明するのがそんなに難しいのか分かりません
BlackTigerX '29

へへ…ええ、私はどうすればもっと簡単にできるようになったのか本当にわかりません:)
lomaxx '30 / 07/30

2
これは実際には私にとってより明確です。最初はセッションごとで、2番目はマルチセッション用で、覚えておくのは簡単です。2回投票することはできませんか?:D
黒先生

1
1次キャッシュが必要な理由のサンプルはありません。私はほとんどの場合それはまったく必要ありません。しかし、あなたはそれとセッションについて常に考えるべきです。
2013年

この回答から11年、残念ながらリンクは現在存在しません。しかし、私はそのコンテンツをアーカイブウェブページで見つけました:web.archive.org/web/20081207044228/http
Golu

105

ここでは、休止キャッシュの基本的な説明をいくつか示します...

一次キャッシュは「セッション」オブジェクトに関連付けられています。キャッシュオブジェクトのスコープはセッションです。セッションが閉じられると、キャッシュされたオブジェクトは永久に失われます。一次キャッシュはデフォルトで有効になっており、無効にすることはできません。エンティティを初めてクエリするとき、エンティティはデータベースから取得され、休止状態セッションに関連付けられた1次キャッシュに格納されます。同じセッションオブジェクトで同じオブジェクトを再度クエリすると、キャッシュから読み込まれ、SQLクエリは実行されません。ロードされたエンティティは、evict()メソッドを使用してセッションから削除できます。evict()メソッドを使用して削除されている場合、このエンティティの次回の読み込みでは、再びデータベース呼び出しが行われます。clear()メソッドを使用して、セッションキャッシュ全体を削除できます。キャッシュに保存されているすべてのエンティティを削除します。

2次キャッシュは、セッションファクトリスコープでグローバルに使用できる1次キャッシュとは異なります。2次キャッシュはセッションファクトリスコープで作成され、その特定のセッションファクトリを使用して作成されるすべてのセッションで使用できます。また、セッションファクトリが閉じられると、それに関連付けられているすべてのキャッシュが停止し、キャッシュマネージャーも閉じられます。休止状態のセッションがエンティティを読み込もうとするときはいつでも、最初の場所でエンティティのキ​​ャッシュされたコピーを探します(特定の休止状態のセッションに関連付けられている)。エンティティのキ​​ャッシュされたコピーが一次キャッシュに存在する場合、loadメソッドの結果として返されます。1次キャッシュにエンティティがキャッシュされていない場合、2次キャッシュがキャッシュされたエンティティを検索します。2次キャッシュにエンティティがキャッシュされている場合は、loadメソッドの結果として返されます。だが、エンティティを返す前に、エンティティは1次レベルキャッシュにも格納されるため、エンティティのloadメソッドを次に呼び出すと、1次レベルキャッシュ自体からエンティティが返され、2次レベルキャッシュに再度移動する必要はありません。エンティティが第1レベルのキャッシュと第2レベルのキャッシュにも見つからない場合、データベースクエリが実行され、エンティティは両方のキャッシュレベルに格納されてから、load() 方法。


2
素晴らしい説明!あなたがいくつかのシーケンス図を描くことができればそれは素晴らしいでしょう!!!
アデリン2017

徹底的で素晴らしい説明
ManishS

1
すでに知っていることを修正したい場合は、Dennis CとIomaxxによる上記の2つの答えは素晴らしく、非常に簡潔で覚えやすいものです。ただし、違いがわからないときに違いの説明を探している場合は、この答えの方がはるかに優れています。
The Student Soul

素晴らしい説明!!
blu3

17

これは非常に一般的な質問なので、この回答は私がブログに書いたこの記事に基づいています。

一次キャッシュ

Hibernateは最後の可能な瞬間まで永続化コンテキストのフラッシュを延期しようとします。この記事で説明したように、この戦略は伝統的にトランザクション後書きと呼ばれていました。

後書きは、論理的または物理的なトランザクションではなく、Hibernateフラッシュに関連しています。トランザクション中に、フラッシュが複数回発生することがあります。

ここに画像の説明を入力してください

フラッシュされた変更は、現在のデータベーストランザクションでのみ表示されます。現在のトランザクションがコミットされるまで、変更は他の同時トランザクションからは見えません。

一次キャッシュのため、Hibernateはいくつかの最適化を行うことができます。

2次キャッシュ

適切なキャッシングソリューションは、複数のHibernateセッションにまたがる必要があるため、Hibernateが追加の2次キャッシュもサポートするのはそのためです。

2次キャッシュはSessionFactoryライフサイクルにバインドされているため、SessionFactoryが閉じられたとき(通常、アプリケーションがシャットダウンしているとき)にのみ破棄されます。2次キャッシュは、オプションのクエリキャッシュソリューションもサポートしていますが、主にエンティティベース指向です。

詳しくは、こちらの記事をご覧ください。


3

デフォルトでは、NHibernateはセッションオブジェクトベースの第1レベルのキャッシュを使用します。ただし、マルチサーバー環境で実行している場合、一次レベルのキャッシュは、いくつかのパフォーマンスの問題とともに、あまりスケーラブルでない可能性があります。これは、データが複数のサーバーに分散されているため、非常に頻繁にデータベースにアクセスする必要があるためです。言い換えると、NHibernateは、基本的な、それほど洗練されていないインプロセスL1キャッシュをそのまま提供します。ただし、キャッシュソリューションがアプリケーションのパフォーマンスに大きな影響を与える必要がある機能は提供されません。

したがって、これらすべての問題の問題は、セッションファクトリオブジェクトに関連付けられているL2キャッシュの使用です。データベースへの時間のかかる移動が減少するため、最終的にアプリの応答時間が増加します。


1

一次キャッシュ

セッションオブジェクトは、第1レベルのキャッシュデータを保持します。デフォルトでは有効になっています。第1レベルのキャッシュデータは、アプリケーション全体で使用できません。アプリケーションは多くのセッションオブジェクトを使用できます。

2次キャッシュ

SessionFactoryオブジェクトは、第2レベルのキャッシュデータを保持します。2次キャッシュに保存されたデータは、アプリケーション全体で利用できます。ただし、明示的に有効にする必要があります。


-4

2次レベルのキャッシュでは、ドメインのhbmファイルはキーが変更可能で、値がfalseである可能性があります。たとえば、このドメインクラスでは、1日の期間の一部が普遍的な真理として一定のままです。したがって、アプリケーション全体で不変としてマークすることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.