В большинстве случаев проблемы с пулами соединений связаны с «утечками соединений». Ваше приложение, вероятно, не закрывает свои подключения к базе данных правильно и последовательно. Когда вы оставляете соединения открытыми, они остаются заблокированными, пока сборщик мусора .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.