Насколько это плохо, чтобы Dispose () SqlConnections?

14

Лично я вырываюсь в ульи, если не помещаю объекты ADO, которые реализуют IDisposable, в операторы использования. Но в моем текущем контракте я обнаружил, что их собственный код «провайдера доступа к данным» корпоративной инфраструктуры не 1) реализует IDisposable и 2) не вызывает Dispose () для всего, что он использует, в любой момент, когда-либо. Пользователи много жаловались на проблемы с производительностью в приложениях Winforms, которые интенсивно используют эту платформу для доступа к данным, и хотя в коде есть множество других проблем, которые могут повлиять на производительность, эта просто кричит на меня и больше низко висящий фрукт, чем другие.

Итак, помимо того, что вы говорите что-то вроде «Уничтожить, есть причина»

Эй Джей Джонсон
источник
5
Хех ... я думаю, что в какой-то момент убедить не нужно будет :)
доктор Ганнибал Лектер

Ответы:

6

Я бы сказал, что лучшее, что вы можете сделать, это указать им на «Шаблоны и практики Microsoft», касающиеся Dispose() здесь . Пусть они увидят все последствия неиспользования этого инструмента, который прямо перед ними.

Джесси С. Слайсер
источник
1
Просто хотелось бы найти версию, которая не кричала "это удаленный контент" наверху.
AJ Джонсон
Вы знаете, мои глаза просто затуманились из-за этого. Но теперь, читая это внимательно, мне интересно, какие технологии, которые люди могут «по-прежнему использовать», удалены с этой страницы. Может быть, CAS?
Джесси С. Slicer
Сканируя это более внимательно, большая часть этого все еще кажется мне актуальной. Не уверен, почему он помечен как пенсионер.
AJ Джонсон
10

Если вы не вызываете метод Dispose для соединения SQL, когда вы его используете, это соединение НЕ возвращается обратно в пул соединений.

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

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

Вальтер
источник
Вызова Closeдостаточно для возврата обратно в пул соединений. Вопрос не гласит, что Closeне используется явно .
user2864740
9

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

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

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

Дин Хардинг
источник
1
Это даже немного хуже, чем это. Если резервное копирование пула будет выполнено достаточно, многие попытки подключения в конечном итоге будут просто неудачными, включая попытки подключения из инструментов управления, и вы сможете эффективно заблокировать нашу базу данных.
Джоэл Коухорн
3

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

~Object()
{
    this.Dispose(false);    
}

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    // ...
}

Взять, System.Data.SqlClient.SqlConnectionк примеру:

System.ComponentModel.Component <- Реализует шаблон удаления Finalize.
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

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

ChaosPandion
источник
0

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

Я бы предположил, б) из-за удара производительности вы описываете. Однако это, вероятно, не единственная причина.

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


источник