Можно ли получить утечки подключения sql с помощью LINQ?

Я полагал, что при использовании LINQ невозможно получить утечки соединения sql, но отслеживание Perfmon NumberOfReclaimedConnections показывает большое число, и при высокой нагрузке мы иногда получаем исключения, такие как «Истекло время ожидания. Время ожидания истекло до получения соединения из пула. Это могло произойти из-за того, что все соединения в пуле использовались и был достигнут максимальный размер пула ".

Мы не используем Dispose для текстов данных, так как мы использовали отложенную загрузку. Несколько статей и сообщений в блоге говорят мне, что это не должно быть проблемой.

Тем не менее, иногда у нас бывают эти исключения. Но не может быть, что каждый запрос linq, который мы действительно поддерживаем, поддерживает соединение, тогда у нас будет намного больше исключений.

Отредактировано

Приложение представляет собой службу WCF.

Если вы посмотрите документацию Linq и большинство статей, они утверждают, что Dispose не требуется для освобождения соединений. Они утверждают, что DataCOntext поддерживает соединение открытым только на короткое время.


person Atle    schedule 23.04.2009    source источник


Ответы (3)


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

Даже если вы используете отложенную загрузку и не имеете четко определенной области, вы все равно должны очищать соединения с базой данных в конце логической единицы работы. В приложениях ASP.NET самый последний возможный момент для этого - конец обработки запроса - в методе Application_EndRequest файла Globals.asax. В службе WCF любой активный контекст данных следует удалять в конце каждого вызова метода службы.

Документация по этому поводу расплывчата, и хотя в большинстве случаев вы можете обойтись без удаления своего DataContext, есть некоторые сценарии, в которых данные, загруженные из соединения, поддерживают само соединение. Самый простой способ подтвердить, что это происходит в вашем случае, - это протестировать.

person Ronald Wildenberg    schedule 23.04.2009

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

Я сделал этот небольшой тестовый код, который его воспроизводит. Если я просто заменяю Enumerator на foreach, он работает нормально, но Enumerator сохраняет соединения открытыми.

public Organisation RunTestQuery2()
{
    IEnumerable<Organisation> orgs  = base.GetEntities<Organisation>().Take(5);

    var enumerator = orgs.GetEnumerator();
    int i = 0;


    while (enumerator.MoveNext())
    {
        var org = enumerator.Current;
        Debug.WriteLine(org.DescribingName);
        if (i == 3)
        {
           return org;
        }
        i++;
    }

    return null;
}

Если я добавлю вызов dispose в контекст, они исчезнут.

person Atle    schedule 23.04.2009
comment
Это просто волшебство компилятора. foreach - это синтаксическая конфетка для создания экземпляра Enumerator, вызывающего MoveNext до тех пор, пока он не вернет false, а затем вызывает Dispose для Enumerator. Просто к вашему сведению. - person Kilanash; 07.07.2011

Есть ли у вас тупиковые ситуации в вашей базе данных? Быстрый взгляд на Монитор активности должен дать вам некоторое представление.

Что вы делаете для управления жизненным циклом DataContext - какое приложение вы написали (веб-сайт, клиент Windows, другое)?

После использования в запросе или операции DataContext будет поддерживать соединение, так что загруженные объекты могут лениво загружаться и т. Д., Поэтому крайне важно, чтобы вы спланировали, как вы используете DataContexts в своем приложении.

Сервисы WCF ... В этом случае я большой поклонник подхода "один контекст на запрос". Я бы посоветовал вам заключить свои операции с данными в оператор using (), чтобы контекст был удален, когда вы закончите.

person RobS    schedule 23.04.2009
comment
У нас нет проблем с тупиками, по крайней мере, у меня, насколько я знаю на данный момент, и мы отслеживаем это. Приложение - это службы WCF, и контекст данных никогда не должен существовать дольше, чем вызов службы. - person Atle; 23.04.2009