/ / NHibernate - クエリは新しいエンティティを保存した後にクエリキャッシュを逃します。 - c#、nhibernate、fluent-nhibernate、linq-nhibernate

NHibernate - クエリは新しいエンティティを保存した後でクエリキャッシュを逃します。 - c#、nhibernate、fluent-nhibernate、linq-nhibernate

私はNHibernateを持っている NHibernate.Linq そして 流暢なNHibernate)クエリキャッシュを使用して設定します。私がするまではすべてうまく動作します session.Save(new Widget()) (すなわちSQL INSERT)。その時点以降、そのタイプのすべてのクエリ Widget クエリキャッシュが不足しています。他のエンティティタイプのクエリはキャッシュされます。

using (ISession session = MySessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
// this INSERT screws things up
var widget = new Widget {Name = "Foo"};
session.Save(widget);

var query = (from w in session.Query<Widget>().Cacheable()
where w.Name == "Bar"
select w);

var fetched1 = query.FirstOrDefault();
var fetched2 = query.FirstOrDefault(); // miss?!

transaction.Commit();
}
}

私が新しい Transaction、問題は続く。私が新しい Session、問題は解消されます。私の理解が2番目のレベルのキャッシュだったので、これは奇妙なようです SessionFactory (ない Session)。

私はこのことについては考えていませんが、私は HashtableCacheProvider私はちょうど今テストしているからです。

回答:

回答№1は6

あなたが記述した行動は正しい もっと見る.

更新タイムスタンプキャッシュは、ユーザーがコミットするまで更新されません。 トランザクション!これは、 "コミットされていない" 値をキャッシュから削除します。

変更があった場合はいつでも type 完全なトランザクションがコミットされるまで、キャッシュキャッシュされたデータは失効しています。

このフィルタの結果をキャッシュしたとします。

 var query = (from w in session.Query<Widget>().Cacheable()
where w.Name == "B*" // all names starting with B
select w);

そして、後で新しいウィジェットを追加します:

var widget = new Widget {Name = "Brigitte"};
session.Save(widget);
// explicit Flush is not needed,
// but then, until Commit(), query will never return Brigitte
session.Flush(); // to immediately execute INSERT

クエリがまだキャッシュされる場合、ブリジットは表示されません...

Transactionでは、FirstOrDefault()を使用したクエリがただちに実行されます。書き込み操作は、Flush on Commitを待つことができます。

取引のために、操作(挿入、udpate、選択)はキャッシュから利益を得ることはできません。コミットが呼び出されるまで、キャッシュは使用できませんでした。

多くの詳細で有用な情報がここにあります: NHibernateにおける第1および第2レベルのキャッシュ

タイムスタンプキャッシュは、テーブルに書き込まれるたびに更新されますが、トリッキーな方法で更新されます。

  • 実際の文章を書くときは、キャッシュの将来のどこかにある値。したがって、 キャッシュはそれを見つけられず、新しいデータを取得するためにDBにヒットします。 私たちは取引の途中にいるので、 トランザクションを終了します。低い隔離レベルを使用している場合、 別のスレッド/マシンは古い結果を キャッシュでは、更新タイムスタンプが 未来。
  • トランザクションでコミットを実行すると、タイムスタンプキャッシュを現在の値で更新します。