回答:
1.1)一次キャッシュ
1次キャッシュは常にSessionオブジェクトに関連付けられます。Hibernateはデフォルトでこのキャッシュを使用します。ここでは、1つのトランザクションを次々に処理します。つまり、1つのトランザクションを何度も処理しないということです。主に、特定のトランザクション内で生成する必要があるSQLクエリの数を減らします。これは、トランザクションで行われたすべての変更の後に更新するのではなく、トランザクションの最後にのみトランザクションを更新します。
1.2)2次キャッシュ
2次キャッシュは常にセッションファクトリオブジェクトに関連付けられます。トランザクションの実行中、その間にオブジェクトがセッションファクトリレベルで読み込まれるため、これらのオブジェクトは、シングルユーザーにバインドされずに、アプリケーション全体で利用できます。オブジェクトは既にキャッシュに読み込まれているため、クエリによってオブジェクトが返されるときはいつでも、データベーストランザクションを実行する必要はありません。このようにして、2次キャッシュが機能します。ここではクエリレベルのキャッシュも使用できます。
引用元:http : //javabeat.net/introduction-to-hibernate-caching/
Streamline Logicブログには、第1レベルのキャッシングに関するかなり良い説明があります。
基本的に、第1レベルのキャッシュはセッションごとに行われ、第2レベルのキャッシュは複数のセッション間で共有できます。
ここでは、休止キャッシュの基本的な説明をいくつか示します...
一次キャッシュは「セッション」オブジェクトに関連付けられています。キャッシュオブジェクトのスコープはセッションです。セッションが閉じられると、キャッシュされたオブジェクトは永久に失われます。一次キャッシュはデフォルトで有効になっており、無効にすることはできません。エンティティを初めてクエリするとき、エンティティはデータベースから取得され、休止状態セッションに関連付けられた1次キャッシュに格納されます。同じセッションオブジェクトで同じオブジェクトを再度クエリすると、キャッシュから読み込まれ、SQLクエリは実行されません。ロードされたエンティティは、evict()
メソッドを使用してセッションから削除できます。evict()
メソッドを使用して削除されている場合、このエンティティの次回の読み込みでは、再びデータベース呼び出しが行われます。clear()
メソッドを使用して、セッションキャッシュ全体を削除できます。キャッシュに保存されているすべてのエンティティを削除します。
2次キャッシュは、セッションファクトリスコープでグローバルに使用できる1次キャッシュとは異なります。2次キャッシュはセッションファクトリスコープで作成され、その特定のセッションファクトリを使用して作成されるすべてのセッションで使用できます。また、セッションファクトリが閉じられると、それに関連付けられているすべてのキャッシュが停止し、キャッシュマネージャーも閉じられます。休止状態のセッションがエンティティを読み込もうとするときはいつでも、最初の場所でエンティティのキャッシュされたコピーを探します(特定の休止状態のセッションに関連付けられている)。エンティティのキャッシュされたコピーが一次キャッシュに存在する場合、loadメソッドの結果として返されます。1次キャッシュにエンティティがキャッシュされていない場合、2次キャッシュがキャッシュされたエンティティを検索します。2次キャッシュにエンティティがキャッシュされている場合は、loadメソッドの結果として返されます。だが、エンティティを返す前に、エンティティは1次レベルキャッシュにも格納されるため、エンティティのloadメソッドを次に呼び出すと、1次レベルキャッシュ自体からエンティティが返され、2次レベルキャッシュに再度移動する必要はありません。エンティティが第1レベルのキャッシュと第2レベルのキャッシュにも見つからない場合、データベースクエリが実行され、エンティティは両方のキャッシュレベルに格納されてから、load()
方法。
これは非常に一般的な質問なので、この回答は私がブログに書いたこの記事に基づいています。
Hibernateは最後の可能な瞬間まで永続化コンテキストのフラッシュを延期しようとします。この記事で説明したように、この戦略は伝統的にトランザクション後書きと呼ばれていました。
後書きは、論理的または物理的なトランザクションではなく、Hibernateフラッシュに関連しています。トランザクション中に、フラッシュが複数回発生することがあります。
フラッシュされた変更は、現在のデータベーストランザクションでのみ表示されます。現在のトランザクションがコミットされるまで、変更は他の同時トランザクションからは見えません。
一次キャッシュのため、Hibernateはいくつかの最適化を行うことができます。
適切なキャッシングソリューションは、複数のHibernateセッションにまたがる必要があるため、Hibernateが追加の2次キャッシュもサポートするのはそのためです。
2次キャッシュはSessionFactoryライフサイクルにバインドされているため、SessionFactory
が閉じられたとき(通常、アプリケーションがシャットダウンしているとき)にのみ破棄されます。2次キャッシュは、オプションのクエリキャッシュソリューションもサポートしていますが、主にエンティティベース指向です。
詳しくは、こちらの記事をご覧ください。
デフォルトでは、NHibernateはセッションオブジェクトベースの第1レベルのキャッシュを使用します。ただし、マルチサーバー環境で実行している場合、一次レベルのキャッシュは、いくつかのパフォーマンスの問題とともに、あまりスケーラブルでない可能性があります。これは、データが複数のサーバーに分散されているため、非常に頻繁にデータベースにアクセスする必要があるためです。言い換えると、NHibernateは、基本的な、それほど洗練されていないインプロセスL1キャッシュをそのまま提供します。ただし、キャッシュソリューションがアプリケーションのパフォーマンスに大きな影響を与える必要がある機能は提供されません。
したがって、これらすべての問題の問題は、セッションファクトリオブジェクトに関連付けられているL2キャッシュの使用です。データベースへの時間のかかる移動が減少するため、最終的にアプリの応答時間が増加します。