Насколько важно для меня объединить мои связи? - PullRequest
4 голосов
/ 14 марта 2010

Мне было предложено переставить код для «объединения» моих ADO-соединений. На каждой веб-странице я бы открывал одно соединение и продолжал использовать одно и то же открытое соединение. Но кто-то еще сказал мне, что это было важно 10 лет назад, но не так важно сейчас. Если я сделаю, скажем, 5 дБ вызовов на веб-публикацию, будет ли проблематично использовать 5 отдельных подключений, которые я открываю / закрываю?

Ответы [ 6 ]

3 голосов
/ 14 марта 2010

Соединения с SQL Server автоматически объединяются в приложении ASP.NET: один пул для каждой отдельной строки соединения. Если вы следуете рекомендациям и скрываете код своей базы данных в DAL, строка подключения которого постоянна во всем приложении, то вы всегда будете работать с одиночным пулом объектов подключения.

Так что это значит для вашего подхода к базе данных? Ну, во-первых, это означает, что «закрытие соединения» действительно означает «возвращение соединения в пул», а не действительно закрытие ссылки приложения на SQL Server. Таким образом, закрытие и повторное открытие - это не , что большой сделки. Тем не менее, с учетом сказанного, есть несколько лучших практик, которым нужно следовать здесь.

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

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

В-третьих, я настоятельно рекомендую не открывать соединение в начале жизненного цикла страницы и не закрывать его в конце жизненного цикла другим способом. Зачем? Потому что худшее , что вы можете сделать, это оставить соединение открытым, потому что вы забыли добавить логику, чтобы закрыть его. Да, они в конечном итоге будут закрыты, когда GC начнет действовать, но, опять же, если вы подумаете о "тысячах людей, использующих эту страницу *, шанс для реальной проблемы станет очевидным.

Теперь, что если вы скажете, что вы уверены, что закроете соединение, потому что вы всегда делаете это в каком-то ключевом, логическом месте (например, метод Page_Unload). Что ж, это здорово , если вы можете с уверенностью сказать, что никогда не выбросите ошибку, которая выпрыгнет из жизненного цикла страницы. Что вы не можете. Так что ... не открывайте в одном методе жизненного цикла страницы и не закрывайте в другом.

Наконец, я настоятельно рекомендую реализовать DAL, который управляет соединениями с базой данных и предоставляет инструменты для работы с данными. Кроме того, создайте слой бизнес-логики (BLL), который использует эти инструменты для предоставления типизированных объектов в ваш пользовательский интерфейс (например, объекты «модель»). Если вы реализуете объекты BLL с интерфейсом IDisposable, вы всегда можете обеспечить безопасность соединения, используя область действия. Это также позволит вам держать соединение с базой данных открытым в течение очень короткого периода времени: просто откройте объект BLL, перетащите данные в локальный объект или список, а затем закройте объект BLL (выйдите из области видимости ). Затем вы можете работать с данными, возвращаемыми BLL после соединения было закрыто.

Итак ... как это выглядит. Итак, на ваших страницах (пользовательском интерфейсе) вы будете использовать классы бизнес-логики, например:

using (BusinessLogicSubClass bLogic = new BusinessLogicSubClass())
{
   // Retrieve and display data or pull from your UI and update
   // using methods built into the bLogic object
    .
    .
    .
}  // <-- Going out of scope will automatically call the dispose method and close the database connection.

Ваш BusinessLogicSubClass будет производным от объекта BusinessLogic, который реализует IDisposable. Он создаст экземпляр вашего класса DAL и откроет соединение следующим образом:

public class BusinessLogic : IDisposable
{
    protected DBManagementClass qry;
    public BusinessLogic()
    {
        qry = new DBManagementClass();
    }

    public void Dispose()
    {
        qry.Dispose();  <-- qry does the connection management as described below.
    }

    ... other methods that work with the qry class to 
    ... retrieve, manipulate, update, etc. the data 
    ... Example: returning a List<ModelClass> to the UI ...

 }

когда класс BusinessLogic выходит из области видимости, автоматически вызывается метод Dispose, поскольку он реализует интерфейс IDisposable.

Ваш класс DAL будет иметь подходящие методы:

public class DBManagementClass : IDisposable
{
    public static string ConnectionString { get; set; }  // ConnectionString is initialized when the App starts up.

    public DBManagementClass()
    {
        conn = new SqlConnection(ConnectionString);  
        conn.Open();
    }

    public void Dispose()
    {
        conn.Close();
    }

    ... other methods
}

Учитывая то, что я описал до сих пор, DAL не имеет для IDisposable. Тем не менее, я активно использую свой класс DAL в своем тестовом коде, когда тестирую новые методы BLL, поэтому я создал DAL как IDisposable, чтобы я мог использовать конструкцию «using» во время тестирования.

Следуйте этому подходу, и, по сути, вам больше никогда не придется думать о пуле соединений.

3 голосов
/ 14 марта 2010

В Framework 2.0 ASP.NET по умолчанию объединяет подключения к SQL Server.

Однако то, о чем говорят люди, с которыми вы разговаривали, не совсем одно. Скорее речь идет об уменьшении количества сеансов базы данных.

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

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

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

3 голосов
/ 14 марта 2010

Если вы используете ADO.NET с SQL Server, ваши соединения, вероятно, уже объединены. В наши дни пул соединений является очень распространенной практикой с базами данных, и большую часть времени вы используете пул, не зная об этом. Я предполагаю, что вам сказали, что ручное объединение соединений не так уж важно, так как сейчас это обычно происходит автоматически.

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

2 голосов
/ 14 марта 2010

ADO.NET часто объединяет ваши соединения в любом случае. Это иногда считается хорошей вещью; он изо всех сил пытается сделать правильные вещи и, вероятно, не вызовет никакого горя.

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

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

2 голосов
/ 14 марта 2010

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

Что если вы масштабируете до 15 вызовов базы данных? Эти соединения начинают накапливаться.

Объединить их. Нет причины не делать этого.

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

1 голос
/ 14 марта 2010

Ключевым моментом, который я нашел, является время, необходимое для создания соединения с базой данных.

Для сервера MSSQL, работающего на медленном соединении на полпути по всему миру, объединение в пул значительно улучшит скорость отклика вашего приложения.

При локальной установке MySQL вы можете не увидеть существенной разницы.

...