Узнайте, где sql серверные соединения остаются открытыми в c# - PullRequest
1 голос
/ 21 июня 2020

Я унаследовал тонну кода C# do tnet, который, по-видимому, в каком-то месте не закрывает соединение или что-то еще с сервером sql, и я получаю

The timeout period elapsed prior to obtaining a connection from the pool: This may have occurred because all pooled connections were in use and max pool size was reached

Это происходит довольно часто и обычно в одно и то же время, но я не знаю ничего, что запланировано. Кроме того, поиск вручную в каждом небольшом месте кода совершенно невозможен. Есть идеи, как исправить это, не перебирая вручную каждую функцию в коде?

1 Ответ

1 голос
/ 22 июня 2020

Проблема с нежеланием go проходить через код заключается в том, что очень вероятно, что это не отдельный экземпляр или область и может зависеть от того, где вы получаете c наибольший трафик в производственной среде. У вас может быть довольно безобидный запрос, который можно немного улучшить с помощью .AsNoTracking() или лучшего соединения / включения, а не одного большого запроса, который плохо оптимизирован. Бывают также случаи, когда весь дизайн ошибочен (однажды я попал в проект, где sql соединений были прикреплены к отдельным классам, поэтому не было реального способа обернуть соединение в оператор using. Нам пришлось реструктурировать все из него.

Если вы используете настраиваемые транзакции или sql запросы на соединение, убедитесь, что вы обертываете с использованием и try catch finally с удалением. Полагаться на сборщик мусора не всегда хорошо так как нет гарантии, что сборщик мусора на самом деле dispose сразу в конце оператора using.

using (var conn = new SqlConnection())
{
    try
    {
        // Transactions, SQL Commands, etc
    }
    catch (SqlException ex)
    {
        // Trans rollback, error handling
    }
    finally
    {
        // Tell the garbage collector to clean up this resource now.
        conn.Dispose();
    }
}

Если вы строго используете контекст базы данных, некоторые операторы можно оптимизировать незначительно, используя .AsNoTracking() для случаев, когда вы только извлекаете набор результатов, но не собираетесь изменять результаты этого запроса. Примерно следующее:

var tier = _dbContext.Tier.AsNoTracking()
    .Include(t => t.NameSchema)
    .Include(t => t.TierPackageGroups)
    .Where(t => t.TierNumber == tierNumber).FirstOrDefault();

Убедитесь, что вы используете соединения или .Include везде, где возможно, в отличие от отложенной загрузки.

Это не тот ответ, который вы хотите h ухо, и я был на вашем месте, но, скорее всего, лучшее решение - это go через код. Вы всегда можете начать с очистки нескольких областей, измерения удара, еще нескольких областей, измерения удара и т. Д. c. Подобное расследование может помочь сузить область поиска, поскольку вы видите улучшения в одних областях или не видите некоторых в других.

Если вы уверены, что это должен быть единственный запрос, который вы хотите найти, тогда есть инструменты для оценки sql производительности, но я обычно обращаюсь к администратору базы данных, чтобы справиться с этим, поэтому я не знаком с этими инструментами. Если вы используете Azure, есть панель, где вы можете видеть запросы и организовывать их по влиянию на производительность. Он не укажет вам на код, но он может дать вам подсказку.

Поскольку вопрос предназначен специально для решения, которое не требует поиска кода, еще один ответ, который будет работать, - это просто добавьте больше оборудования для решения проблемы, но это плохой временный интервал, который может быть дорогостоящим и в конечном итоге просто откладывает проблему или решает проблему только в 99% случаев (пока вы не достигнете периода пиковой нагрузки c, для пример). Один клиент, который у нас был несколько лет назад, вероятно, потратил более 50 тысяч долларов на дополнительные расходы на хостинг, тогда как на момент первоначального запроса он мог бы попросить нас исправить проблему менее чем за 5 тысяч долларов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...