Ответ 1
Придерживайтесь опции a.
Объединение пулов - ваш друг.
У меня есть моя бизнес-логика, реализованная в простых статических классах со статическими методами. Каждый из этих методов открывает/закрывает SQL-соединение при вызове:
public static void AddSomething(string something)
{
using (SqlConnection connection = new SqlConnection("..."))
{
connection.Open();
// ...
connection.Close();
}
}
Но я думаю, что избегать открытия и закрытия соединения экономит производительность. Я сделал несколько тестов времени займет слишком много назад с OleDbConnection класса (не уверен, SqlConnection), и это, безусловно, помогло работать так (насколько я помню):
//pass the connection object into the method
public static void AddSomething(string something, SqlConnection connection)
{
bool openConn = (connection.State == ConnectionState.Open);
if (!openConn)
{
connection.Open();
}
// ....
if (openConn)
{
connection.Close();
}
}
Итак, вопрос в том, должен ли я выбрать метод (а) или метод (б)? Я прочитал еще один вопрос о stackoverflow о том, что объединение пулов меняет производительность для меня, мне не нужно беспокоиться вообще...
PS. Это приложение ASP.NET - соединения существуют только во время веб-запроса. Не win-приложение или услуга.
Придерживайтесь опции a.
Объединение пулов - ваш друг.
Использовать метод (a) каждый раз. Когда вы начнете масштабировать свое приложение, логика, связанная с состоянием, станет реальной болью, если вы этого не сделаете.
Пул соединений делает то, что он говорит на жестяной банке. Просто подумайте о том, что произойдет, когда приложение масштабируется, и насколько сложно было бы вручную управлять открытием/закрытием соединения. Пул соединений прекрасно справляется с этим. Если вы беспокоитесь о производительности, подумайте о каком-то механизме кэширования памяти, чтобы ничто не блокировалось.
Всегда закрывайте соединения, как только вы закончите с ними, поэтому базовое соединение с базой данных может вернуться в пул и быть доступным для других абонентов. Пул соединений довольно хорошо оптимизирован, поэтому нет заметного штрафа за это. Совет в основном такой же, как и для транзакций, - держите их короткими и закрытыми, когда закончите.
Это становится более сложным, если вы сталкиваетесь с проблемами MSDTC, используя единую транзакцию вокруг кода, который использует несколько соединений, и в этом случае вам действительно нужно разделить объект соединения и закрыть его только после выполнения транзакции.
Однако вы делаете что-то вручную, поэтому вы можете изучить инструменты, которые управляют подключениями для вас, такие как DataSets, Linq to SQL, Entity Framework или NHibernate.
Отказ от ответственности: Я знаю, что это старо, но я нашел простой способ продемонстрировать этот факт, поэтому я вкладываю в свои две центы.
Если у вас возникли проблемы с верой в то, что объединение действительно будет быстрее, попробуйте:
Добавьте следующее:
using System.Diagnostics;
public static class TestExtensions
{
public static void TimedOpen(this SqlConnection conn)
{
Stopwatch sw = Stopwatch.StartNew();
conn.Open();
Console.WriteLine(sw.Elapsed);
}
}
Теперь замените все вызовы на Open()
на TimedOpen()
и запустите свою программу. Теперь, для каждой отдельной строки соединения, у вас есть консольное (выходное) окно, будет иметь один длинный запуск, и очень скоро откроется куча очень быстрого доступа.
Если вы хотите пометить их, вы можете добавить new StackTrace(true).GetFrame(1) +
к вызову WriteLine
.
Существуют различия между физическими и логическими соединениями. DbConnection - это своего рода логическое соединение, и он использует базовое физическое соединение с Oracle. Закрытие/открытие DbConnection не влияет на вашу производительность, но делает ваш код чистым и стабильным - утечка соединения в этом случае невозможна.
Также вы должны помнить о случаях, когда существуют ограничения для параллельных соединений на сервере db - учитывая это, необходимо очень коротко сделать ваши соединения.
Пул соединений освобождает вас от проверки состояния соединения - просто откройте, используйте и немедленно закройте их.