Як же погано не розпоряджатися () SqlConnections?


14

Особисто я вириваюсь у вуликах, якщо не ставлю об’єкти ADO, які реалізують IDisposable у використанні операторів. Але в моєму нинішньому контракті я виявив, що їхнє кодове підприємство "провайдер доступу до даних" не включає 1) реалізацію IDisposable і 2) виклик Dispose () на будь-що, чим він користується, в будь-який момент і ніколи. Користувачі скаржаться на проблеми з продуктивністю в додатках Winforms, які активно використовують цю рамку для доступу до даних, і хоча в коді є багато інших проблем, які можуть вражати продуктивність, ця просто кричить на мене і більше фрукти низькорослі, ніж інші.

Отже, окрім того, щоб сказати щось на кшталт "розпоряджайся причиною, використовуй це", що я можу сказати цим людям, щоб переконати їх у тому, що це справді, дуже погано?


5
Хе .. я здогадуюсь, що в певний момент переконувати не буде потрібно :)
д-р Ганнібал Лектер

Відповіді:


6

Я б сказав, що найкраще, що ви можете зробити, - це вказати їх на «Шаблони та практики Microsoft», що стосуються Dispose() тут . Нехай вони побачать усі наслідки невикористання цього інструменту, який знаходиться прямо перед ними.


1
Просто хочу, щоб я міг знайти версію, яка не кричала "це вміст у відставці" вгорі.
AJ Johnson

Знаєте, мої очі просто заблищали це. Але зараз уважно читаючи це, мені цікаво, які технології, які люди "все ще можуть використовувати", відкликані з цієї сторінки. Можливо, CAS?
Джессі К. Слікер

Скануючи це більш уважно, більшість із цього все ще здається мені актуальним. Не впевнений, чому це позначено і пенсіонером.
AJ Johnson

10

Якщо ви не зателефонували методу Dispose на підключенні SQL, під час його використання це з'єднання НЕ повертається назад до пулу з'єднань.

Якщо у вас виникають проблеми з продуктивністю, я гадаю, що максимальна кількість з'єднань відкрита у вашій базі даних. DBA може це легко підтвердити.

Найкраща практика Microsoft вимагає розміщення коду підключення всередині оператора Use, що забезпечує утилізацію з'єднання та повернення з'єднання назад у пул.


Виклику Closeдостатньо, щоб повернутися до пулу з'єднань. У запитанні не зазначено, що явноClose не використовується.
користувач2864740

9

Пул підключення до бази даних обмежений за розміром, і якщо він заповниться, нові з'єднання будуть чекати виходу старих з'єднань. Якщо ви не розпоряджаєтесь ними, як тільки ви закінчите з ними, вони з часом будуть звільнені, коли фіналізер запуститься, але це невизначена кількість часу в майбутньому ... Тож у кращому випадку ви збираєтесь побачити довгі затримки під час відкриття нових з'єднань.

У гіршому випадку, можливо, вони відключили пул зв’язків. Можливо, вони виявили, що через деякий час їх додаток повертає помилки "очікування очікування на з'єднання" і відключення пулу з'єднань "вирішило" цю проблему. Однак це набагато гірше, оскільки це означає, що ви створюєте цілком нове з'єднання кожного разу - що на диво багато ресурсів. Якщо у вас відкриті сотні підключень до бази даних, не дивно, що ви бачите проблеми з продуктивністю.

Правильний спосіб вирішити всі ці проблеми - розпоряджатися своїм зв’язком, як тільки ви закінчите з ним. Найкраща ідея - тримати з'єднання відкритим рівно стільки часу, скільки потрібно, і більше.


1
Це навіть трохи гірше, ніж це. Якщо резервний пакет буде забезпечено достатньою кількістю резервів, багато спроб підключення з часом просто не вдасться, включаючи спроби підключення з інструментів управління, і ви можете ефективно заблокувати нашу базу даних.
Joel Coehoorn

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 <- реалізує схему завершення розпорядження.
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

Об'єкти врешті-решт будуть утилізовані, але недетермінований характер викликає погіршення продуктивності.


0

Ну, для одного, ви не припиняєте з'єднання. Таким чином, це або повинно: а) автоматично випадати або b) проходити цикл та оновлюватись, навіть якщо клієнт не має для цього користі.

Я б припустив, що б) через хіт ефективності, який ви описуєте. Однак це, мабуть, не єдина причина.

Ви ОБОВ'ЯЗКОВО закриєте підключення, бажано на стороні клієнта, але Ви також маєте реалізувати безпечну помилку на стороні сервера. В іншому випадку у вас просто набрано додаткове лайно на тому, що ваш сервер баз даних повинен обробляти, поки він не буде випущений у богобій-коли.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.