"открыть/закрыть" SqlConnection или оставить открытым?

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

Ответ 1

Придерживайтесь опции a.

Объединение пулов - ваш друг.

Ответ 2

Использовать метод (a) каждый раз. Когда вы начнете масштабировать свое приложение, логика, связанная с состоянием, станет реальной болью, если вы этого не сделаете.

Пул соединений делает то, что он говорит на жестяной банке. Просто подумайте о том, что произойдет, когда приложение масштабируется, и насколько сложно было бы вручную управлять открытием/закрытием соединения. Пул соединений прекрасно справляется с этим. Если вы беспокоитесь о производительности, подумайте о каком-то механизме кэширования памяти, чтобы ничто не блокировалось.

Ответ 3

Всегда закрывайте соединения, как только вы закончите с ними, поэтому базовое соединение с базой данных может вернуться в пул и быть доступным для других абонентов. Пул соединений довольно хорошо оптимизирован, поэтому нет заметного штрафа за это. Совет в основном такой же, как и для транзакций, - держите их короткими и закрытыми, когда закончите.

Это становится более сложным, если вы сталкиваетесь с проблемами MSDTC, используя единую транзакцию вокруг кода, который использует несколько соединений, и в этом случае вам действительно нужно разделить объект соединения и закрыть его только после выполнения транзакции.

Однако вы делаете что-то вручную, поэтому вы можете изучить инструменты, которые управляют подключениями для вас, такие как DataSets, Linq to SQL, Entity Framework или NHibernate.

Ответ 4

Отказ от ответственности: Я знаю, что это старо, но я нашел простой способ продемонстрировать этот факт, поэтому я вкладываю в свои две центы.

Если у вас возникли проблемы с верой в то, что объединение действительно будет быстрее, попробуйте:

Добавьте следующее:

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.

Ответ 5

Существуют различия между физическими и логическими соединениями. DbConnection - это своего рода логическое соединение, и он использует базовое физическое соединение с Oracle. Закрытие/открытие DbConnection не влияет на вашу производительность, но делает ваш код чистым и стабильным - утечка соединения в этом случае невозможна.

Также вы должны помнить о случаях, когда существуют ограничения для параллельных соединений на сервере db - учитывая это, необходимо очень коротко сделать ваши соединения.

Пул соединений освобождает вас от проверки состояния соединения - просто откройте, используйте и немедленно закройте их.