В большинстве случаев проблемы с пулами соединений связаны с «утечками соединений». Ваше приложение, вероятно, не закрывает свои подключения к базе данных правильно и последовательно. Когда вы оставляете соединения открытыми, они остаются заблокированными, пока сборщик мусора .NET не закроет их для вас, вызвав их Finalize()метод.
Вы хотите убедиться, что вы действительно закрываете соединение . Например, следующий код вызовет утечку соединения, если код между .Openи Closeвыдает исключение:
var connection = new SqlConnection(connectionString);
connection.Open();
// some code
connection.Close();
Правильный путь будет такой:
var connection = new SqlConnection(ConnectionString);
try
{
connection.Open();
someCall (connection);
}
finally
{
connection.Close();
}
или
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
someCall(connection);
}
Когда ваша функция возвращает соединение из метода класса, убедитесь, что вы кэшируете его локально и вызываете его Closeметод. Вы потеряете соединение, используя этот код, например:
var command = new OleDbCommand(someUpdateQuery, getConnection());
result = command.ExecuteNonQuery();
connection().Close();
Соединение, возвращенное с первого звонка, getConnection()не закрывается. Вместо того, чтобы закрывать ваше соединение, эта строка создает новое и пытается закрыть его.
Если вы используете SqlDataReaderили OleDbDataReader, закройте их. Несмотря на то, что закрытие самого соединения, кажется, делает свое дело, приложите дополнительные усилия для явного закрытия объектов чтения данных при их использовании.
В этой статье « Почему переполнение пула соединений? » Из журнала MSDN / SQL объясняется много деталей и предлагаются некоторые стратегии отладки:
- Запустите
sp_whoили sp_who2. Эти системные хранимые процедуры возвращают информацию из sysprocessesсистемной таблицы, которая показывает состояние и информацию обо всех рабочих процессах. Как правило, вы увидите один идентификатор процесса сервера (SPID) для каждого соединения. Если вы назвали свое соединение, используя аргумент «Имя приложения» в строке соединения, ваши рабочие соединения будет легко найти.
- Используйте SQL Server Profiler с
TSQL_Replayшаблоном SQLProfiler для отслеживания открытых соединений. Если вы знакомы с Profiler, этот метод проще, чем опрос с использованием sp_who.
- Используйте системный монитор для мониторинга пулов и соединений. Я обсуждаю этот метод через минуту.
- Мониторинг счетчиков производительности в коде. Вы можете отслеживать состояние вашего пула соединений и количество установленных соединений, используя процедуры извлечения счетчиков или используя новые элементы управления .NET PerformanceCounter.