NHibernate クエリがハングし始めるという非常に奇妙な動作が発生しています。この動作を再現可能な方法で示すデモ プロジェクトを作成しました。
プロジェクトはこちらからダウンロードできます
問題のあるコードは次のとおりです。
public IList<Post> GetLatestLiveBlogEntries(int numEntriesToRetrieve)
{
var maxDate = DateTime.Now;
using (var session = SessionManager.OpenSession())
{
var crit = session.CreateCriteria(typeof (Post))
.Add(Restrictions.Eq("Enabled", true))
.Add(Restrictions.Lt("postDate", maxDate))
.AddOrder(new Order("postDate", false))
//.SetFetchMode("author", FetchMode.Eager) // <-- the exclusion of this line breaks everything!
.SetMaxResults(numEntriesToRetrieve);
StupidFileLogger.Log("If this is the last log, I'm hanging on crit.List<Post>()");
var listOfPosts = crit.List<Post>();
StupidFileLogger.Log("I actually was able to retrieve the posts");
return listOfPosts;
}
}
重要な行は、作成者フィールドの .SetFetchMode です。私のデモ プロジェクトの最初のロードでは、正常にロードされます。更新を押すとハングし、crit.List() 呼び出しを通過しません。熱心な読み込みでは、いつでも機能します。
Castle.Facilities.NHibernateIntegration.Components.SessionWebModule を使用して、リクエストごとに 1 つのセッションを確保しています。
私が見つけたもう1つの奇妙なことは、これがSQL Serverでのみ発生することです。SQLite を使用すると、すべて正常に動作します。私のデモ プロジェクトでは、db を簡単に切り替えることができる単純なビルド フラグがあります。/build ディレクトリの local.properties.xml を見てください。
この特定のケースでは、熱心な読み込みによって問題が解決されることは理解していますが、私のアプリケーションでは、すべてを熱心に読み込む必要はありません。
ソリューションをダウンロードして、自分で試してみてください。他のマシンで試してみましたが、同じことをします。
SQL プロファイラーのキャプチャを次に示します。Posts のクエリがサーバーに送信されたことがわかりますが、そこで停止します。
最初のリクエスト (期待どおりに動作):
いいリクエスト http://muc-central.com/misc/good_request.jpg
2 番目の要求 (ハング):