ASP.NET Статический объект для хранения соединения с БД.Это хорошая идея? - PullRequest
2 голосов
/ 20 июля 2010

Мне интересно, будет ли это хорошим подходом в проекте ASP.NET, если я задаю поле, которое «держит» соединение с БД в качестве статического поля (Entity Framework)

public class DBConnector
{
    public static AdServiceDB db;
    ....
}

Это означает, что это будет только один объект для всего приложения для связи с БД.Мне также интересно, будет ли этот объект обновлять изменения данных из таблиц БД , или, возможно, он не должен быть статическим, и я должен создать соединение с помощью диниами.Что ты думаешь?

Ответы [ 7 ]

4 голосов
/ 20 июля 2010

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

3 голосов
/ 20 июля 2010

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

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

3 голосов
/ 20 июля 2010

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

Надеюсь, это поможет

Использование одиночного соединения для подключения - хорошая идея на веб-сайте ASP.NET

1 голос
/ 20 июля 2010

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

0 голосов
/ 20 ноября 2010

Так как ни один из ответов не был помечен как ответ, и я не думаю, что кто-либо действительно адресовал вопрос или проблему ...

В ASP.NET у вас есть глобальное или HttpApplication.Это работает так, что IIS будет кэшировать экземпляры вашего «приложения» (это экземпляр вашего глобального класса).Обычно (настройки по умолчанию в IIS) у вас может быть до 10 экземпляров Global, и IIS выберет любой из этих экземпляров для удовлетворения запроса.

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

В IIS также есть понятие Пулов приложений и рабочих процессов.Рабочий процесс будет размещать ваше приложение и все экземпляры ваших глобальных классов (как обсуждалось ранее).Таким образом, это переводится в домен приложения (в терминах .NET).

Просто подытожим, прежде чем двигаться дальше ...

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

Двигаемся дальше ...

Поскольку в домене приложения будет только один экземпляр статического класса, вы фактически будете иметь один экземпляр вашего класса, общий для всех (до 10) экземпляров Global,Это плохая идея, потому что, когда несколько одновременных запросов попадут на ваш сервер, они будут либо заблокированы (если методы вашего класса используют блокировки), либо потоки будут наступать друг другу на пальцы.Другими словами, этот подход не является поточно-ориентированным по своей природе, и если вы делаете его поточно-безопасным с помощью примитивов синхронизации потоков, то вы без необходимости блокируете потоки, отрицательно влияя на производительность и масштабируемость вашего веб-приложения, без какой-либо выгоды.

Реальное решение (и я использую это во всех моих приложениях ASP.NET) состоит в том, чтобы иметь экземпляр вашего BLL или DAL (в зависимости от обстоятельств) для экземпляра Global.Это обеспечит следующее: 1. Несколько потоков не являются проблемой, поскольку IIS гарантирует один запрос-ответ на экземпляр Global) в любой данный момент времени.Таким образом, ваш код по своей сути безопасен для потоков.2. В любой момент времени у вас есть только до 10 экземпляров вашего BLL / DAL, которые гарантируют, что вы не будете постоянно создавать и утилизировать экземпляры (обычно) больших объектов для удовлетворения каждого запроса, что на загруженных сайтахогромный 3. Вы получаете действительно хорошую производительность благодаря № 2.

Вы должны убедиться, что ваш BLL / DAL действительно не имеет состояния или что вы сбрасываете любое состояние в начале каждого цикла запрос-ответ.Вы можете использовать событие BeginRequest в Global, чтобы сделать то, что вам нужно.

Если вы пойдете по этому пути, обязательно прочитайте мой блог в этом

Insttiing Business Layers- ASP.NET

0 голосов
/ 20 июля 2010

Я думаю, что рекомендация "часто обновляться".

0 голосов
/ 20 июля 2010

Я бы сказал нет.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...