エンティティに遅延プロパティが存在する場合、NHibernateのcriteria.List()がハングする
-
22-07-2019 - |
質問
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番目のリクエスト(ハング):
解決 2
LinFu proxyfactory.factory_classに切り替えることでハングを修正しました。これがなぜ機能するのか、Castleが機能しないのかはわかりません。ダイナミックプロキシの詳細を確認し、提出する必要があるバグレポートの種類を見つけます。
他のヒント
まあ、これはWindowsサーバーで実行されていると思うので、htopに相当するものはわかりませんが、データベース/セッションコードのどこかにデッドロックがあり、スレッドの状態をチェックして確認する必要がありますすべてのスレッドは待機状態です。