Насколько это плохо, чтобы 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

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


0

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.