Критерии NHibernate.List () зависают, когда для объекта существует ленивое свойство

У меня было очень странное поведение, когда запросы 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, все работает нормально. В моем демонстрационном проекте у меня есть простой флаг сборки, который позволяет легко переключать базы данных. Просто посмотрите файл local.properties.xml в каталоге / build.

Я понимаю, что в данном конкретном случае нетерпеливая загрузка решает мою проблему, но в моем приложении я не хочу, чтобы все загружалось с нетерпением.

Загрузите решение и попробуйте сами. Я пробовал это на других машинах, и они делают то же самое.

Вот несколько записей SQL Profiler. Вы можете видеть, что запрос сообщений был отправлен на сервер, но он останавливается на этом:

Первый запрос (ведет себя так, как ожидалось):

http://muc-central.com/misc/good_request.jpg

Второй запрос (зависает):

http://muc-central.com/misc/hanging_request.jpg


person Scott Muc    schedule 24.06.2009    source источник
comment
Как долго вы оставили его в обработке? Вы уверены, что он действительно завис, а не просто очень занят в течение длительного периода времени? Вы когда-нибудь использовали NH Profiler, чтобы узнать, что делает NH, когда вы вызываете список ‹› во второй раз?   -  person Shane Courtrille    schedule 24.06.2009
comment
Я оставил его включенным, пока пошел обедать, а он все еще не закончился. Я протестировал его с помощью NHProf и увидел, что запрос попал на сервер БД. Я также могу сказать это через SQL Server Profiler.   -  person Scott Muc    schedule 25.06.2009


Ответы (2)


Что ж, я предполагаю, что это работает на сервере Windows, поэтому я не знаю эквивалента htop, но держу пари, что где-то в коде базы данных / сеанса есть тупик, и вы должны иметь возможность проверить состояние потока, чтобы увидеть, все ли потоки в состоянии ожидания.

person Community    schedule 24.06.2009
comment
Добро пожаловать в StackOverflow rdickie ;-) Только что обнаружил, что он отлично работает с SQLite. Начинаю думать, что это проблема с подключением к БД, но все еще нужно сузить ее. - person Scott Muc; 25.06.2009

Я исправил зависание, перейдя на LinFu proxyfactory.factory_class. Понятия не имею, почему это работает, а Касл - нет. Собираюсь узнать больше о динамических прокси и выяснить, какой отчет об ошибке мне следует отправить.

person Scott Muc    schedule 28.06.2009