0

我遇到了一些非常奇怪的行为,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 个会话。

我发现的另一件奇怪的事情是这只发生在 SQL Server 上。当我使用 SQLite 时,一切正常。在我的演示项目中,我有一个简单的构建标志,可让您轻松切换数据库。只需查看 /build 目录中的 local.properties.xml。

我知道在这种特殊情况下急切加载解决了我的问题,但在我的应用程序中,我不想急切加载所有内容。

请下载解决方案并自己尝试。我在其他机器上试过,他们做同样的事情。

以下是一些 SQL Profiler 捕获。您可以看到 Posts 的查询已发送到服务器,但它停在那里:

第一个请求(按预期运行):

好的请求 http://muc-central.com/misc/good_request.jpg

第二个请求(挂起):

替代文字 http://muc-central.com/misc/hanging_request.jpg

4

2 回答 2

0

好吧,我假设这是在 Windows 服务器上运行的,所以我不知道与 htop 等效,但我敢打赌,数据库/会话代码中的某处存在死锁,您应该能够检查线程状态以查看每个线程是否是处于等待状态。

于 2009-06-24T21:28:47.983 回答
0

我通过切换到 LinFu proxyfactory.factory_class 解决了这个问题。不知道为什么这行得通,而城堡却不行。将进一步了解动态代理并找出我应该提交什么样的错误报告。

于 2009-06-28T08:07:08.623 回答