問題タブ [syscache2]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - NHibernate SysCache2 とクエリ キャッシュ - Select N+1 を避けることはできませんか?
Fluent NHibernate で第 2 レベルのキャッシュ プロバイダー SysCache2 を使用し、標準的な流暢な構成 (一般的なアドバイスのようにクエリ キャッシュを有効にする) を使用し、テーブル ベースの依存関係を通常の方法で定義しています。
流暢:
)
Web.Config:
ユーザー マッピング:
単一のリクエストに対してすべてが期待どおりに実行されます。つまり、次のようになります。
NHibernate が IDでキャッシュする方法から予想されるとおりです。後続のリクエストはデータベースにヒットせず、データベース内のレコードを無効にするとエンティティが無効になり、次のリクエスト中に後続の SQL 呼び出しが発生します。大丈夫。
問題はクエリのキャッシュにあります。最初の例では、すべて正常に動作します。次のような呼び出しを実行します。
期待どおりの SQL 呼び出しになります (SELECT * FROM Users WHERE Active = true)。その後の実行では、SQL は発生しません。偉大な。クエリ セットの 1 つのレコードがデータベースで変更されるまで。同じクエリを実行すると、SELECT N+1 になります。
解決策はありませんが、他の場所でこれへの参照を見つけました:
StackOverflow - NHibernate キャッシュ フェッチされた子コレクションを作成するにはどうすればよいですか? 「もう 1 つのポイント」セクションを参照してください
最後に「エンティティもキャッシュされる」ことを保証するAyende Caching Strategiesに言及
現時点でこれを回避できる唯一の方法は、リクエストごとにクエリキャッシュをクリアすることです。これにより、ほとんど役に立たなくなります。個々のレコードだけでなく、エンティティが無効化されたときに、クエリ キャッシュが特定のエンティティのすべてをクリアするために必要なこと。
何か案は?
asp.net - SessionFactory.Evict の副作用?
社内アプリケーションに既にキャッシュされているデータベース内の 1 つまたは複数のビジネス エンティティを変更する作業を頻繁に行うことがあります。アプリ プールを循環させずにアプリケーションにこれらの変更を反映させるために、開発者/管理者がアプリの UI 内から (完全にまたは特定のオブジェクトに対して) キャッシュを削除する機能を組み込むことを考えましたが、次のコメントに気付きました。メソッドは次のように述べています...
それは正確にはどういう意味ですか?トランザクションに関与している可能性のある 1 つまたは複数のオブジェクトを削除しようとすると、何が問題になる可能性がありますか? また、それらが破壊的な場合、これらの副作用を回避する方法はありますか? 私は現在 SysCache2 を使用しており、SqlDependency の使用方法に関する実装の詳細を探していますが、当面の Evict 効果についてはまだ興味があります。
更新:コメントをよく見ると、プロセス レベルのキャッシュから削除し、2 番目のレベルのキャッシュから削除するようにSessionFactory.Evict()
見えSessionFactory.EvictCollection()
ますSessionFactory.EvictEntity()
。ただし、どちらのフレーバーにも同じ免責事項があります。だから私の最初の質問はまだ残っています。別のトランザクションで現在使用されているエンティティをキャッシュ (プロセスまたは第 2 レベル) から削除すると、どのような危険がありますか?
nhibernate - nhibernate L2 キャッシング: コードで設定
コードで第 2 レベルのキャッシュを構成する方法 (xml 経由ではない)
私が持っている現在の設定は次のとおりです。
nhibernate - NHibernate ルックアップ テーブル キャッシング + SqlCacheDependency
NHibernate の第 2 レベルのキャッシュ プロバイダー SysCache2 と SqlCacheDependency を使用して、ルックアップ テーブルのキャッシュを構成しようとしています。
単一の Country テーブルでフレームワークをテストしていますが、NHibernate のログを読むと、キャッシュが機能しないことがわかります..そして、その理由がわかりません。
私は無知です:/
SqlCacheDependency は、データベースとテーブル LUT_Countries で有効になっています。
Web.Config:
流暢な構成:
NHibernate の Country Fluent マッピング:
Hibernate のログ:
...
14:20:53.544 : DEBUG : キャッシュ対象: CountryRegion 使用方法: 読み取り専用
14:20:53.546 : WARN : 変更可能な読み取り専用キャッシュが構成されています: CountryRegion
14:20:53.551 : DEBUG : 構成からキャッシュ領域「CountriesRegion」を構築しています
14:20:53.559 : DEBUG : キャッシュ領域の構成
14:20:53.559 : DEBUG : 優先度を使用: デフォルト
14:20:53.559 : DEBUG : 相対有効期限 :7.00:00:00 を使用
14:20:53.571 : DEBUG: SQL テーブルの依存関係、テーブルを使用した「Countries」、「LUT_Countries」、およびデータベース エントリを構成しています。'デフォルト'
...
14:20:53.811 : DEBUG : クラス SessionFactoryObjectFactory を初期化しています
14:20:53.813: デバッグ: 登録済み: 311e0b6b7e7a41b289b4347267f963f9 (名前なし)
14:20:53.813: 情報: 名前が構成されていません
14:20:53.813 : DEBUG : インスタンス化されたセッション ファクトリ
14:20:53.817 : 情報: リージョンで更新タイムスタンプ キャッシュを開始しています: UpdateTimestampsCache
14:20:53.817 : DEBUG : 構成されていないキャッシュ領域を構築しています : UpdateTimestampsCache
14:20:53.817 : DEBUG : キャッシュ領域の構成
14:20:53.817 : DEBUG : デフォルトを使用して優先順位が指定されていません : デフォルト
14:20:53.817: DEBUG: デフォルトを使用して有効期限が指定されていません: 00:05:00
14:20:53.819 : 情報: リージョンでクエリ キャッシュを開始しています: NHibernate.Cache.StandardQueryCache
14:20:53.819 : DEBUG : 構成されていないキャッシュ領域を構築しています : NHibernate.Cache.StandardQueryCache
14:20:53.819 : DEBUG : キャッシュ領域の構成
14:20:53.819 : DEBUG : デフォルトを使用して優先順位が指定されていません : デフォルト
14:20:53.819 : DEBUG : デフォルトを使用して有効期限が指定されていません: 00:05:00
14:20:53.825 : DEBUG : 0 個の名前付き HQL クエリをチェックしています
14:20:53.825 : DEBUG : 0 個の名前付き SQL クエリをチェックしています
14:20:53.868 : DEBUG : [session-id=76cd9097-abc6-49f4-9fcb-2f5a0ca446ae] がタイムスタンプでセッションを開きました: 5622576143695872、セッション ファクトリの場合: [/311e0b6b7e7a41b289b4347267f963f9]
14:20:54.169 : DEBUG : 式 (部分的に評価): 値 (NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country])
14:20:54.191 : DEBUG : HQL クエリ プランがキャッシュにありません。生成 (NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country])
14:20:54.922 : DEBUG : 選択 << 開始 [レベル = 1、ステートメント = 選択]
14:20:54.957: DEBUG: FromClause{level=1}: Web.DataAccess.ORM.Models.Country ( 0) -> country0
14:20:54.992: デバッグ: 解決済み: 0 -> country0 .Code
14:20:55.000 : DEBUG : 選択 : 仕上げ中 [レベル=1、ステートメント=選択]
14:20:55.004 : DEBUG : processQuery() : ( SELECT ( {select 句} country0_.Code ) ( FromClause{level=1} LUT_Countries country0_ ) )
14:20:55.065 : DEBUG : FROM フラグメントの使用 [LUT_Countries country0_]
14:20:55.070 : DEBUG : 選択 >> 終了 [レベル = 1、ステートメント = 選択]
14:20:55.073: デバッグ: throwQueryException(): エラーなし
14:20:55.199 : DEBUG : SQL: country0_.Code を Code1_ として、country0_.Name を Name1_ として、country0_.Alpha3_IsoCode を Alpha3_1_ として、country0_.NumericCode を NumericC4_1_ として LUT_Countries country0_ から選択します
14:20:55.199: デバッグ: throwQueryException(): エラーなし
14:20:55.255 : DEBUG : HQL クエリ プランがキャッシュにありました (NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country])
14:20:55.263: デバッグ: 検索: NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country]
...
14:20:55.639 : DEBUG : 結果セット行: 11
14:20:55.639 : DEBUG : 「AP」を列として返す: Code1_
14:20:55.639 : DEBUG : 結果行: EntityKey[Web.DataAccess.ORM.Models.Country#AP]
14:20:55.639 : DEBUG : DataReader からオブジェクトを初期化しています: [Web.DataAccess.ORM.Models.Country#AP]
14:20:55.639 : DEBUG : ハイドレーティング エンティティ: [Web.DataAccess.ORM.Models.Country#AP]
14:20:55.639 : DEBUG: 「アジア/太平洋地域」を列として返す: Name1_
14:20:55.639 : DEBUG : 「AP」を列として返す: Alpha3_1_
14:20:55.639 : DEBUG: 列として '0' を返す: NumericC4_1_
14:20:55.639 : DEBUG : 結果セット行: 12
...
14:20:55.701: デバッグ: IDataReader を閉じて、IDataReaders を開きます:0
14:20:55.702 : DEBUG : DataReader は 290 ミリ秒後に閉じられました
14:20:55.704: DEBUG: IDbCommand を閉じ、IDbCommands を開きます: 0
14:20:55.707 : DEBUG : データベース接続を積極的に解放しています
14:20:55.707 : DEBUG : 接続を閉じています
14:20:55.713 : DEBUG : ハイドレートされたオブジェクトの合計: 251
14:20:55.722 : DEBUG : [Web.DataAccess.ORM.Models.Country#A1] の関連付けを解決しています
14:20:55.730 : DEBUG : 第 2 レベルのキャッシュにエンティティを追加します: [Web.DataAccess.ORM.Models.Country#A1]
14:20:55.736: デバッグ: キャッシュ: Web.DataAccess.ORM.Models.Country#A1
14:20:55.740 : DEBUG : リージョンのルート キャッシュ アイテムが見つかりません。
14:20:55.744 : DEBUG : キャッシュ リージョンのルート キャッシュ エントリを作成しています: CountryRegion
14:20:55.745 : DEBUG : 変更通知のキャッシュ依存関係を登録しています
14:20:56.042 : DEBUG : キャッシュの依存関係をルート キャッシュ エントリにアタッチしています。変更が検出されると、キャッシュ エントリは削除されます。
14:20:56.045 : DEBUG : 新しいデータの追加: key=NHibernate-Cache:CountriesRegion:Web.DataAccess.ORM.Models.Country#A1@-1467239096 & value=NHibernate.Cache.Entry.CacheEntry
14:20:56.047 : DEBUG : アイテムの有効期限: 2013 年 7 月 8 日 17:20:56
14:20:56.058 : DEBUG : 実体化完了 [Web.DataAccess.ORM.Models.Country#A1]
14:20:56.061 : DEBUG : [Web.DataAccess.ORM.Models.Country#A2] の関連付けを解決しています
14:20:56.061 : DEBUG : 第 2 レベルのキャッシュにエンティティを追加します: [Web.DataAccess.ORM.Models.Country#A2]
14:20:56.061: デバッグ: キャッシュ: Web.DataAccess.ORM.Models.Country#A2
... ... .
5 秒後に 2 回目の実行を行うと、最初と同じように新しい SQL クエリが生成され、次のログの多くが出力されます (戻り値とキャッシュへの登録:
15:17:34.076 : DEBUG : [session-id=e1feb78d-6c3e-40a4-8b46-6d5742bd0f85] タイムスタンプでセッションを開きました: 5622590071095296、セッション ファクトリの場合: [/0ee3e73fbf6741d28adcff632c68b671]
15:17:34.077 : DEBUG : 式 (部分的に評価): 値 (NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country])
15:17:34.077 : DEBUG : HQL クエリ プランがキャッシュにありました (NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country])
15:17:34.077 : DEBUG : HQL クエリ プランがキャッシュにありました (NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country])
15:17:34.077: デバッグ: 検索: NHibernate.Linq.NhQueryable`1[Web.DataAccess.ORM.Models.Country]
15:17:34.077 : DEBUG : 名前付きパラメータ: {}
15:17:34.077: DEBUG: 新しい IDbCommand を開き、IDbCommands を開きます: 1
15:17:34.077 : DEBUG : SqlString の IDbCommand オブジェクトの作成: country0_.Code を Code1_ として、country0_.Name を Name1_ として、country0_.Alpha3_IsoCode を Alpha3_1_ として、country0_.NumericCode を NumericC4_1_ として LUT_Countries country0_ から選択します
15:17:34.077 : 情報 : country0_.Code を Code1_ として、country0_.Name を Name1_ として、country0_.Alpha3_IsoCode を Alpha3_1_ として、country0_.NumericCode を NumericC4_1_ として LUT_Countries country0_ から選択します
15:17:34.078 : DEBUG : ドライバーから IDbConnection を取得しています
15:17:34.079 : DEBUG : ExecuteReader に 1 ミリ秒かかりました
15:17:34.079 : デバッグ: IDataReader を開き、IDataReaders を開きます: 1
15:17:34.079 : DEBUG : 結果セットの処理
15:17:34.079 : DEBUG : 結果セットの行: 0
15:17:34.080 : DEBUG : 'A1' を列として返す: Code1_
15:17:34.080 : DEBUG : 結果行: EntityKey[Web.DataAccess.ORM.Models.Country#A1]
15:17:34.080 : DEBUG : DataReader からオブジェクトを初期化しています: [Web.DataAccess.ORM.Models.Country#A1]
15:17:34.080 : DEBUG : ハイドレーティング エンティティ: [Web.DataAccess.ORM.Models.Country#A1]
15:17:34.080 : DEBUG : 「匿名プロキシ」を列として返す: Name1_
15:17:34.080 : DEBUG : 'A1' を列として返す: Alpha3_1_
15:17:34.080 : DEBUG : 列として '0' を返す: NumericC4_1_
15:17:34.080 : DEBUG : 結果セットの行: 1
...
c# - NHibernate SysCache2 - 依存関係がキャッシュを壊す
会社のクラス:
会社表:
これが私のweb.configです:
問題: RefData キャッシュ領域内の他のエンティティ (変更されない、国を考えるなど) は正常にキャッシュされます。一方、会社はそうではありません。