Как правило, в программе используется одна или несколько одних и тех же конфигураций подключений. И чтобы разработчику не приходилось создавать по нескольку раз в коде программы фактически одно и тоже подключение, в ADO.NET используется механизм пула подключений. К тому же сама по себе операция создания нового объекта подключений является довольно затратной, и использование пула позволяет оптимизировать производительность приложения.
Пул подключений позволяет использовать ранее созданные подключения. Когда менеджер подключений, который управляет пулом, получает запрос на открытие нового подключения с помощью метода Open()
, то он проверяет все подключения пула.
Если менеджер подключений находит в пуле доступное подключение, которое в текущий момент не используется, то оно возвращается для использования. Если же доступного подключения нет, и максимальный размер пула еще не превышен (по умолчанию размер равен 100), то создается новое подключение. Если доступного подключения нет, но при этом превышен максимальный размер пула, то новое подключение добавляется в очередь и ожидает, пока в пуле не освободится место, и тогда оно станет доступным.
После закрытия подключения с помощью метода Close()
закрытое подключение возвращается в пул подключений, где оно оно готово к повторному использованию при следующем вызове метода Open()
.
Например, несмотря на закрытия подключения программа в обоих случаях будет использовать одно и то же подключение:
1 2 3 4 5 6 7 8 9 10 |
SqlConnection connection; connection = new SqlConnection(connectionString); connection.Open(); Console.WriteLine(connection.ClientConnectionId); connection.Close(); connection.Open(); Console.WriteLine(connection.ClientConnectionId); connection.Close(); |
В пул помещаются подключения только с одинаковой конфигурацией. ADO.NET поддерживает несколько пулов одновременно, и для каждой конфигурации строки подключения создается свой собственный пул.
Все подключения в пуле различаются по нескольким признакам:
- строка подключения
- учетные записи, используемые при подключении
- процесс приложения
В следующем примере в первых двух блоках using будет использоваться одно и то же подключение из пула, поскольку строка подключения будет совпадать:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
string connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=usersdb;Integrated Security=True"; string connectionString2 = @"Data Source=.\SQLEXPRESS;Initial Catalog=players;Integrated Security=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // создается первый пул Console.WriteLine(connection.ClientConnectionId); } using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // подключение извлекается из первого пула Console.WriteLine(connection.ClientConnectionId); } using (SqlConnection connection = new SqlConnection(connectionString2)) { connection.Open(); // создается второй пул, т.к. строка подключения отличается Console.WriteLine(connection.ClientConnectionId); } |
Если параметр Min Pool Size не указан в строке подключения или его значение равно 0, то подключения в пуле будут закрыты после периода отсутствия активности (4-8 минут), либо если разорвана связь с сервером базы данных. Но если значение параметра Min Pool Size больше 0, пул подключений не удаляется, пока не будет выгружен домен приложения AppDomain и не завершится процесс.