Ответ 1
Возможно SqlConnection.ClearPool
?
Я понимаю, что если я создаю экземпляр объекта SqlConnection, я действительно захватываю соединение из пула соединений. Когда я вызову Open(), он откроет соединение. Если я вызываю метод Close() или Dispose() в этом объекте SqlConnection, он возвращается в пул соединений.
Однако это не говорит мне, действительно ли он закрыт, или если у меня все еще есть активное подключение к базе данных.
Как заставить SqlConnection закрываться на сетевом уровне или, по крайней мере, указывать, когда он закрывается?
Пример:
using(SqlConnection conn = new SqlConnection(DBConnString)) {
conn.Open();
SqlCommand cmd = conn.CreateCommand();
...
cmd.ExecuteReader(CommandBehavior.CloseConnection);
...
}
Если соединение было закрыто TRULY, второй и третий прогоны также должны составлять 300 мс. Но я знаю, что соединение не действительно закрыто для этих прогонов (я проверил монитор активности SQL Server). Для выполнения аутентификации и т.д. Не требуется дополнительных 200 мс.
Как принудительно закрыть соединение?
Идеи
Ссылки
Возможно SqlConnection.ClearPool
?
Ответ Moe Sisko (Call SqlConnection.ClearPool
) правильный.
Иногда вам нужно подключение, чтобы действительно закрыть, а не возвращаться в пул. В качестве примера у меня есть unit test, который создает базу данных с нуля, строит схему, проверяет некоторые вещи, а затем удаляет базу данных нуля, если все тесты проходят.
Когда активен пул соединений, команда базы данных отказов завершается сбоем, так как все еще есть активные соединения. С точки зрения программиста все SQLConnections закрыты, но поскольку пул по-прежнему остается открытым, SQL Server не позволит отказаться.
Лучшая документация по обработке пула соединений - эта страница в пуле соединений SQL Server в MSDN. Нельзя полностью отключать объединение пулов, поскольку оно повышает производительность при повторном открытии и закрытии, но иногда вам нужно вызвать "принудительное закрытие" на SQLConnection, чтобы он отпустил базу данных.
Это делается с помощью ClearPool. Если вы вызываете SqlConnection.ClearPool(connection)
перед закрытием/удалением, когда вы закрываете/удаляете, это действительно исчезнет.
Если вы не хотите использовать пул соединений, вы должны указать его в свойстве SqlConnection.ConnectionString
. Например
"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"
Устранение или закрытие объекта SqlConnection
просто закрывает соединение и возвращает его в пул соединений.
Как правило, вы хотите, чтобы пул соединений выполнял свою работу - вы не хотите, чтобы соединение действительно закрывалось.
Почему именно вы хотите, чтобы соединение не возвращалось в пул?
Я вижу, что вы используете .net, но, как это выяснилось в запросе Google, позвольте мне дать ответ Java...
Используйте DataSource, который реализует Closeable(), и вызывайте close для DataSource. Хикари поддерживает Closeable.
CommandBehavior.CloseConnection
обычно обескураживается из-за этого самого факта - вы не можете быть уверены, что соединение будет закрыто. (Я попытаюсь найти некоторые конкретные доказательства этого, я говорю это от слабого отзыва).
Dispose()
является самым верным способом, поскольку он неявно вызывает Close()
.
Конструкция using
, продемонстрированная @Alex, - это еще один (программист) способ записи конструкции try-finally
с добавленным неявным удалением объектов.
Изменить: (после редактирования вопроса)
Ваше беспокойство по поводу действительно закрытых соединений кажется мне необоснованным. Соединение просто вернется в пул, чтобы его можно было повторно использовать без необходимости проходить всю инициализацию. Это не означает, что соединение все еще активно подключено к БД.
Роберт ответ SqlConnection.ClearPool(TheSqlConn)
сделал именно то, что я хотел. Приятно знать, с каким пулом можно взаимодействовать, когда это необходимо.
Мой вариант использования: мы испортили соединение и вернули его в пул, как мы обнаруживаем, что он разрушен и обновлен, поэтому у следующего пользователя не будет проблем.
Решение: обнаружение, что мы только что испортили соединение и полностью очистили его от пула, чтобы пул заполнил резервные копии свежими соединениями.
Десятилетие написания SqlClient.SqlConnection, и я даже не думал о взаимодействии с пулом до сегодняшнего дня.