Почему всегда закрывать соединение с базой данных?

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

Например (в псевдокоде):

public class PopulateGridViews()
{
    public SqlConnection conn = new SqlConnection(@"Database:DATABASE");
    conn.Open();

    void PopulateGrid1()
    {
        SqlCommand cmd = new SqlCommand("SELECT * FROM TABLE1");
        cmd.Connection = conn;
        cmd.ExecuteNonQuery();
        cmd.Dispose();
        // Populate Grid1
    }

    void PopulateGrid2()
    {
        SqlCommand cmd = new SqlCommand("SELECT * FROM TABLE2");
        cmd.Connection = conn;
        cmd.ExecuteNonQuery();
        cmd.Dispose();
        // Populate Grid2
    }
}

person yonan2236    schedule 06.11.2010    source источник
comment
Я бы посоветовал прочитать Пул соединений SQL Server (ADO.NET) .   -  person Christopher Painter    schedule 06.11.2010


Ответы (3)


Вы не должны оставлять соединения открытыми.

Вы должны:

  1. Открывайте соединения как можно позже
  2. Закройте соединения как можно скорее

Само соединение возвращается в пул соединений. Связи являются ограниченным и относительно дорогим ресурсом. Любое новое установленное вами подключение, имеющее точно ту же строку подключения, сможет повторно использовать подключение из пула.

Мы настоятельно рекомендуем вам всегда закрывать соединение, когда вы закончите его использовать, чтобы соединение было возвращено в пул. Это можно сделать с помощью методов Close или Dispose объекта Connection или путем открытия всех подключений внутри оператора using в C# или оператора Using в Visual Basic. Соединения, которые не закрыты явно, не могут быть добавлены или возвращены в пул. Дополнительные сведения см. в разделе Использование оператора (справочник по C#) или Практическое руководство. Удаление системного ресурса для Visual Basic. Ссылка.

Вы должны надлежащим образом обернуть все, что реализует IDisposable, в блок операторов using:

 using (SqlConnection connection = new SqlConnection(connectionString))
 {
     connection.Open();

     ...

     command.ExecuteNonQuery();
 }
person Mitch Wheat    schedule 06.11.2010
comment
куда я должен положить свой улов, если во время соединения возникнут какие-то ошибки? - person yonan2236; 06.11.2010
comment
Если вы используете блок использования, как предложил @Mitch Wheat, он будет автоматически закрыт в случае ошибки. - person David; 06.11.2010
comment
Так что нет способа определить, чтобы узнать ошибки, которые произошли? - person yonan2236; 06.11.2010
comment
Нет. Вы можете (и должны) открыть соединение и выполнить команду внутри оператора try. Вы должны сделать это для пользовательского опыта в любом случае. Я не призываю к неправильной обработке ошибок. Я просто говорю, что если вы используете команду using, соединение будет закрыто. Лично я всегда помещаю открытие и выполнение команды в блок «попробовать», а вызов connection.Close() в блок «наконец». - person David; 06.11.2010
comment
@ yonan2236, вы можете попробовать, если хотите, например, выше в приложении. Использование похоже на try-finally, поэтому фактическое исключение не перехватывается, оно распространяется дальше. - person Skurmedel; 06.11.2010
comment
@ Митч Пшеничный, не могли бы вы сказать мне, что вы имеете в виду, говоря, что «Связи» - это ограниченный ресурс? Спасибо. - person dan; 24.05.2014
comment
Если соединение установлено, а затем закрыто из Франции на Ямайку, и оно находится в пуле соединений, то правильно ли предположить, что не требуется никакой связи, кроме отправки данных? - person Damien Golding; 11.07.2014

Потому что (некоторые) базы данных также удерживают открытое соединение, пока вызывающее приложение не скажет закрыть его. Если вы получаете сотни обращений к базе данных, значит, она сидит там со 100 открытыми соединениями, связывающими ресурсы. Нередко тысячи или сотни тысяч обращений к базе данных в загруженном приложении, и рано или поздно производительность БД убьет производительность приложения.

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

В этой статье об этом хорошо сказано (даже если она немного устарела):

http://www.bewebmaster.com/84.php

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

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

person David    schedule 06.11.2010
comment
У нас было приложение, которое мы унаследовали на работе, пропуская соединения, это нехорошо :( Через некоторое время SQL Server перестал отвечать на новые соединения. Это также означало, что все остальные приложения перестали работать. - person Skurmedel; 06.11.2010

Понятно, что если вы не закроете соединение, оно будет постоянно потреблять ваш ресурс, что окажет общее влияние на ваше приложение, и оно также не может быть добавлено или возвращено в пул.

person AbdurRahman Lakhani    schedule 30.07.2018