безопасно ли держать соединения с базой данных открытыми долгое время - PullRequest
32 голосов
/ 23 ноября 2008

У меня есть клиентское приложение .net, которое подключено к удаленной базе данных. Безопасно ли держать одно соединение открытым в течение всего срока службы клиента (часы)?

Ответ удерживается, если у меня запущено несколько (10 или 100) клиентов?

Спасибо

Ответы [ 9 ]

23 голосов
/ 23 ноября 2008

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

Масштабируемость является проблемой или, по крайней мере, раньше, когда машины имели меньше памяти, чем современные комплекты. В двухуровневом приложении (клиент-сервер) каждый клиент открывал соединение и удерживал его открытым. Это имело несколько эффектов:

  • Память использовалась для каждого соединения, поэтому большое количество (относительно) холостых соединения будут использовать машину объем памяти. Тем не менее, современный 64-разрядный Сервер может иметь десятки или сотни ГБ памяти, чтобы он мог поддерживать очень большое количество таких соединения.

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

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

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

Чтобы использовать длинные транзакции (т. Е. Транзакции, которые охватывают более одного обращения к базе данных), необходимо отключить транзакцию от соединения. Это базовая архитектура монитора TP, и существуют некоторые стандартные протоколы, такие как XA или OLE Transactions для поддержки этого. Если этот тип управляемой извне транзакции недоступен, приложение должно создать компенсирующую транзакцию , которая отменяет изменения, внесенные транзакцией приложения. Этот тип архитектуры часто используется системами управления рабочими процессами.

14 голосов
/ 23 ноября 2008

Открытие и закрытие соединения для каждой бизнес-операции

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

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

8 голосов
/ 23 ноября 2008

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

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

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

4 голосов
/ 23 ноября 2008

Хотя конкретные детали имеют значение в целом, нет ничего плохого в том, чтобы держать соединения открытыми в течение длительного времени.

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

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

Клиенты SQLServer, работающие по протоколу TCP, отправляют сообщения активности с интервалом 30 секунд. (Keepalive - это, по сути, 0 лен TCP-пакетов) обычно ожидаемый пренебрежимый трафик.

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

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

Против использования бассейнов:

Удаляет возможность загрязнения окружающей среды - когда другие запросы устанавливают специальные параметры среды, которые могут мешать выполнению запроса (xact_abort, уровни изоляции транзакций и т. Д.)

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

Против подключения каждый раз:

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

2 голосов
/ 23 ноября 2008

Вы, вообще говоря, не должны держать соединения открытыми. .NET имеет систему пулов соединений ADO.NET, которая делает именно то, что вы пытаетесь сделать, и делает это намного лучше. ; -)

обновление: я дебил. размещен в ответ. здесь не применяется.

-Oisin

1 голос
/ 23 ноября 2008

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

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

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

1 голос
/ 23 ноября 2008

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

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

1 голос
/ 23 ноября 2008

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

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

0 голосов
/ 23 ноября 2008

Зависит от базы данных и от того, что вы с ней делаете. Есть расходы на открытие и закрытие любого соединения по большей части. Например, если вы используете SQLCE на мобильном устройстве (SQL Server Compact Edition), то на самом деле рекомендуется оставить соединение открытым на устройстве, поскольку затраты на его открытие и закрытие не стоят хлопот.

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

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