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