Зачем нужен IDisposable для соединения к базе данных?

Интерфейс IDisposable позволяется использовать соединения к базе данных внутри (Или с помощью) using, но зачем такое нужно? Почему тот же MongoDb не нуждается в блоке using. Почему такие вещи вообще не могут работать без закрытия потока?

Для сведения, я понимаю, что за один запрос нужно сделать все нужные операции к базе данных после чего закрыть поток, но ведь открытие/закрытие соединения это дорогостоящая операция, почему нельзя работать с одним экземпляром подключения, хотя бы в рамках single-user-application, не говоря о том же asp.net


Ответы (3 шт):

Автор решения: AlexanderSt

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

Большинство объектов, используемых в программах на C#, относятся к управляемым или managed-коду. Такие объекты управляются CLR и легко очищаются сборщиком мусора. Однако вместе с тем встречаются также и такие объекты, которые задействуют неуправляемые объекты (подключения к файлам, базам данных, сетевые подключения и т.д.). Такие неуправляемые объекты обращаются к API операционной системы. Сборщик мусора может справиться с управляемыми объектами, однако он не знает, как удалять неуправляемые объекты. В этом случае разработчик должен сам реализовывать механизмы очистки на уровне программного кода. Освобождение неуправляемых ресурсов подразумевает реализацию одного из двух механизмов: 1.Создание деструктора 2.Реализация классом интерфейса System.IDisposable

Вы можете не использовать using, а уничтожать объекты самостоятельно. Что касается подключения к БД - далеко не факт, что в момент Connection.Open() открывается новое соединение с БД, а не выделяется уже открытое из пула соединений, находящегося под капотом библиотеки работы с БД.

→ Ссылка
Автор решения: DerSkythe

Выше уже указали на возможные проблемы. Добавлю, что сами вендоры баз данных не любят бесконечные соединения, т.к. на стороне базы тоже выделяются ресурсы, которые могут утекать. Поэтому, даже при использовании connection pool (а в проде его всегда надо использовать), рекомендуется настраивать параметры connection lifetime.

→ Ссылка
Автор решения: Alexander Petrov

открытие/закрытие соединения это дорогостоящая операция

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

почему нельзя работать с одним экземпляром подключения

На самом деле, можно. И зачастую так и рекомендуется делать. Например, в SQLite, где по умолчанию нет пула, часто работают с одним соединением. Это и сериализует доступ к БД, устраняя часть блокировок, и держит в памяти кэш страниц, ускоряя работу.

Почему тот же MongoDb не нуждается в блоке using.

Тут нужно уточнить, что речь о конкретном классе MongoClient из библиотеки для C#.
Ответ: потому что его так сделали. Менеджер поддерживает соединения внутри себя, создавая, открывая и закрывая их по мере необходимости.
Ничто не запрещает сделать другую библиотеку для Монги, в которой будет явное управление соединениями, с наличием Dispose/using.

Как известно, такие языки как C/C++ в основном требует больше ручного управления ресурсами, по сравнению с C#/Java, но именно поэтому они в целом более производительные.

Также ничто не мешает написать библиотеку для работы с реляционными СУБД, в которой будет полностью автоматическое управление соединениями. И такие библиотеки есть. Чтобы не быть голословным, приведу в пример net-Query (попалась мне недавно на глаза).

→ Ссылка