правильная организация соединений с БД
Релиб
Форумы       Участники    Календарь    Кто он-лайн?
Добро пожаловать, гость ( Вход | Регистрация )
        



правильная организация соединений с БД Expand / Collapse
Автор
Сообщение
19.07.2006 23:20
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 02.08.2008 10:18
Сообщ.: 143, Visits: 1 405
Доброе время суток !

Н-да, ламерский вопрос, но тем не менее : Есть приложение ASP.NET, база MSQL 2005, пользователей до 40 человек. Приложение пишет/читает в базу. И вот, совсем запутался - как открывать/закрывать соединение с базой : 1) в каждом web-методе, делающим читающий/пишущий запрос к базе, открывать/закрывать соединение using(SqlConnection ...){...}. Если использовать кеш то, я так понимаю, фактически соединение будет быстрым. 2) создать статическую переменную в ASP.NET приложении и получать от неё объект SqlCommand. Смысла правда не вижу. 3) другое.. 

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

Спасибо.

Men in black

Сообщ. #901078
19.07.2006 23:52
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

администратор
Last Login: 13.11.2007 13:41
Сообщ.: 4 421, Visits: 49 251
благодатная тема для обсуждения...

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

на самом деле материалов на эту тему много, правда, все в конкретном случае зависит от архитектуры приложения и его назначения

Сообщ. #901079
20.07.2006 2:26
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 02.08.2008 10:18
Сообщ.: 143, Visits: 1 405
Admin, если есть ссылки - поделись пожалуйста.

Men in black
Сообщ. #901084
20.07.2006 12:20
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
Я пользуюсь Data Access Application Block из "старой" Microsoft Enterprise Library. Он представляет собой класс (называется SqlHelper) с набором перегруженных static методов для каждого возможного варианта результата. То есть, там есть методы: ExecuteNonQuery(...), ExecuteReader(...) и ExecuteDataSet(...). Эти методы являются просто обертками вокруг соответствующих методов SqlCommand и DataSet. Использовать эти методы очень удобно так как для получения результата вызывается всегда только одна функцию и не нужно явно создавать объекты SqlConnection/SqlCommand. Можно выполнять как текстовые запросы так и хранимые процедуры. Параметры тоже поддерживаются.

На всякий случай я прикрепил к этому посту файл с классом SqlHelper, возможно тебе будет интересно взглянуть на него.

Для доступа к данным использую преимущественно SqlDataReader-ы всегда заключенные в блок using. Соединение создается автоматически внутри класса SqlHelper и автоматически "закроется" в конце блока using так как метод ExecuteReader класса SqlCommand вызывается с параметром CommandBehavior.CloseConnection. Слово "закроется" заключено в кавычки так как ADO.NET ведет пул соединений и закрытие соединения означает возврат его обратно в пул.

Метод из предыдущего абзаца используется в случае, когда страница выполняет только один запрос к БД или запросы разнесены по разным методам. Если же нужно подряд выполнить несколько запросов к одной и той же базе, то я вручную создаю объект SqlConnection (внутри using, конечно) и затем передаю данный экземпляр методам класса SqlHelper.

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

В твоем конкретном случае я бы выбрал метод 1). Методы веб-сервиса, в моем понимании, не должны создавать зависимости между собой, поэтому лучше создавать соединение каждый раз заново. ADO.NET сама ведет пул соединений с базой (можно сказать кеширует) и повторять этот механизм смысла нет. Надо только понимать что в пул не заносятся соединения с windows аутентификацией и ключом для пула соединений является connection string. Причем она сравнивается буквально. Даже если две строки соединения отличаются на один пробел, то соединения созданные с их использованием будут всегда разными и ээфективность пула соединений будет ниже чем могла бы быть.

Метод 2) похож на идею из класса SqlHelper и в принципе тоже может использоваться. Просто для упрощения объема кода который надо писать. Хотя я бы заменил свойство на метод, это выглядит более логично что-ли.

Проблему Admin'a мне бы тоже хотелось понять так как я никогда не испытывал проблем с использованием пула соединений ADO.NET и считал что с ним приложение всегда работает быстрее. А у Admin'a приложение работает быстро при отключенном пуле, и медленно при включенном. Непонятка какая-то :(

Как вариант стоит также рассмотреть использование новой Microsoft Enterprise Library с переписанным Data Application Block. Не могу про него ничего сказать так как никак не соберусь его опробовать. 

Такие вот дела :)


  Post Attachments 
SqlHelper.cs.txt (114 views, 10,16 KB)
Сообщ. #901098
20.07.2006 13:22
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

администратор
Last Login: 13.11.2007 13:41
Сообщ.: 4 421, Visits: 49 251
ссылки надо искать, вот под рукой есть такой материал, который охватывает сразу многие аспекты правильной "организации" приложения, 

там кстати если не ошибаюсь датахелперы советуют не использовать

а для поиска других материалов ключевое слово "performance"

насчет своей проблемы пока ничего толком не откопал, сейчас запустил старое приложение с вкл. пулом под .NET2, в течение дня работает с постоянной нагрузкой 30-50 человек на сайте, с утра вроде бы все быстро, потом начинаются какие-то непонятные тормоза, в общем об этом в другом месте, не будем разводить флейм))

Сообщ. #901116
20.07.2006 14:28
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 02.08.2008 10:18
Сообщ.: 143, Visits: 1 405
Bazile, спасибо от всей души, за столь исчерпывающий ответ ! На данном этапе всё понятно. Использование SqlHelper действительно удобнее. 

Men in black
Сообщ. #901129
21.07.2006 16:30
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 02.08.2008 10:18
Сообщ.: 143, Visits: 1 405
Enterprise Library for .NET Framework 2.0 - January 2006, Data Access Block :

DatabaseFactory.CreateDatabase() генерирует исключение NullReferenceException,  "объекты надо создавать оператором new". Могу предположить, что это связано с конфигурационными настройками.В документации ничего по поводу этого не сказано. Может кто встречал ?

Men in black

Сообщ. #901182
21.07.2006 17:12
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 21.07.2006 17:11
Сообщ.: 484, Visits: 5 211
SQL Server автоматически сам создает пул соединений, соотв. хешем является строчка соединения. Так что ничего ужасного в том, чтобы открывать-закрывать каждый раз нет, соединение все равно берется из пула.
Сообщ. #901187