1

n個のクライアント(現時点では55個)のシステムがあり、各クライアントはまったく同じスキーマを持つ独自のデータベースを取得します。分散ehca​​cheに支えられたhibernate3.6.1を実行しています。これは、実行時に「怠惰に」jvm(HashMapに格納されている)ごとにクライアントごとに1つのSessionFactoryを作成するSessionFactoryServiceを介してデータベースごとにSessionFactoryで実装されているため、SessionFactoriesのアプリケーション管理セットを実行しています。基本的な休止状態の構成ファイルが1つあり、残りの設定は作成時にプログラムで実行されます。私たちのリポジトリ(またはより一般的に呼ばれるDAO)には、SessionFactoryServiceを介してSessionFactoryへのアクセスが許可されます。配布されているSingltonEhcacheRegionFactoryに裏打ちされたHibernateの第2レベルのキャッシュを最大限に活用しています。jvmごとにn個のSessionFactoriesを実行しているため、キャッシュ間の同期を維持しようとしている間、SessionFactories間のjvm間通信が多すぎるため、非SingltonEhacheRegionFactory(つまり、SessionFactoryごとにCacheManagerを持つ)は必要ありません。したがって、必要なのはサーバー間の通信のみであり、サーバー内の通信ではありません。これは、SingltonEhcacheRegionFactoryを介して実現されています。

さて、ここから楽しみが始まります。上記の設定では、データベーススキーマとして一意のキーを保証する方法がないため、キャッシュの衝突が発生します。したがって、それらをサポートするエンティティオブジェクトはSessionFactories全体で同じです。それらを一意にするために、上記のプログラム構成手順を使用して、フィールドhibernate.cache.region_pre-fixをSessionFactoryごとに一意の値に設定しました。これは、第2レベルのキャッシュに関するHibernateの見解を満たしていますが、基盤となるシングルトンehcacheに問題があります。ehache.xml構成ファイルで指定された構成のキャッシュ名にキャッシュプレフィックスがないため、正しい構成を見つけることができません(また、プレフィックスごとにキャッシュ構成ごとに重複するエントリが必要になるため、 n個あります)。これにより、以下のエラーが発生します。

10:37:38,389警告AbstractEhcacheRegionFactory:201-Hibernate構成にTransactionManagerLookupが見つかりません。XAキャッシュは2フェーズコミットに参加します!10:37:39,675警告AbstractEhcacheRegionFactory:143-[some_prefix.adc]という名前のキャッシュの特定のehcache構成が見つかりませんでした。デフォルトを使用します。10:37:40,328警告AbstractEhcacheRegionFactory:143-[some_prefix.org.hibernate.cache.UpdateTimestampsCache]という名前のキャッシュの特定のehcache構成が見つかりませんでした。デフォルトを使用します。10:37:40,331警告AbstractEhcacheRegionFactory:143-[some_prefix.org.hibernate.cache.StandardQueryCache]という名前のキャッシュの特定のehcache構成が見つかりませんでした。デフォルトを使用します。

したがって、問題は、jvm環境ごとに分散された単一のehcacheを使用して複数のSessionFactoryをどのように実現できるかということです。リージョンプレフィックス対応になるようにehcacheを構成する方法はありますか?私たちが実装したソリューションは、せいぜいハッキーです。SingltonEhcacheRegionFactoryを拡張する独自のhibernate.cache.region.factory_classを実装しました(そして、hibernateキャッシュ領域プレフィックス構成を削除しました)。私たちの実装は、基盤となるEhcacheへのメソッド呼び出しをインターセプトし、キャッシュ操作に使用されるすべてのキーにプレフィックスを追加するだけで、キャッシュの衝突を防ぎます。より「すぐに使える」ソリューションが必要であり、明らかな理由から、それは機能しますが、実装したものは理想的ではありません。私はその問題についておそらく見つけることができるすべてを読みましたが、tは、分散された第2レベルのキャッシュを使用して、同じスキーマで(そして最も重要なことに)複数のSessionFactoriesに対処するソリューションを見つけました。任意のアイデア、解決策、またはアドバイスをいただければ幸いです。誰かが要件に対処するための良い方法を持っているなら、私はまったく異なる設計を受け入れることさえできます。前もって感謝します!

4

1 に答える 1

0

上記のセットアップでは、データベース スキーマとして一意のキーを保証する方法がないため、キャッシュの衝突が発生します。したがって、それらをサポートするエンティティ オブジェクトは SessionFactories 全体で同じです。

どう言う意味ですか?すべてのクライアントに同じスキーマを使用している場合、確実に一意のキーを保証する方法があります。これには、UUID の使用や Hibernate の hilo アルゴリズムの使用など、多くの手法があります。

それらを一意にするために、上記のプログラムによる構成手順を介して、フィールド hibernate.cache.region_pre-fix を SessionFactory ごとに一意の値に設定しました。

よくわかりませんでした。一意のキーを取得するには、異なるキャッシュ リージョンが必要だということですか? もしそうなら、それは真実ではありません :-) キャッシュ領域は、エントリ (Car#1、Car#2) ではなく、エンティティ (Car、Person、Account) の「名前空間」であると想定されています。

jvm環境ごとに分散された単一のehcacheを使用して複数のSessionFactoryを実現するにはどうすればよいですか?

複数のセッション ファクトリは問題ありません。ehcache についてはよくわかりませんが、Infinispan のような「キャッシュ サーバー」の使用を検討します。独自の JVM で開始することができ、すべてのクライアントがキャッシュにアクセスしたいときはいつでもそれと対話します。繰り返しますが、あなたの環境を正しく理解しているかどうかはわかりませんが、キャッシュを使用する場合は、Client#1 が参照するデータが Client#2 と同じであることを保証するセットアップを使用する必要があります。

そのため、専用のキャッシュ サーバーを使用して環境をセットアップし、それを使用するようにすべてのセッション ファクトリを構成します。また、説明で見逃していたのは、トランザクションマネージャーです。分散環境を扱う場合、トランザクション管理は、キャッシュ (およびデータベース) 内のデータが古くならず、一貫性があることを保証するために非常に重要です。

Hibernate を使用した Infinispan の詳細については、http://community.jboss.org/wiki/usinginfinispanasjpahibernatesecondlevelcacheprovider を参照してください。

于 2011-03-17T08:02:37.843 に答える