Может ли оператор return помешать оператору using закрыть соединение с базой данных?

StackOverflow https://stackoverflow.com/questions/588396

Вопрос

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

У меня есть следующий код:

using (IDbConnection connection = dbConnectionHandler.CreateConnection())
{
   connection.Open();
   CreateATempTable();
   PopulateTempTable();
   DataSet ds = CallStoredProcThatUsesTempTable();
   return ds;
}

Я использую этот код в нескольких местах для создания временной таблицы с тем же именем.

К сожалению, я получаю следующую ошибку: There is already an object named '#MyTempTable' in the database.

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

Я считаю, что есть три вещи, которые могут вызвать это...

  1. Мне нужно вызвать соединение.Close()
  2. Мне нужно разместить оператор возврата вне моего оператора использования.
  3. Мне нужно удалить временную таблицу, которую я создал перед возвратом

Кто-нибудь знает, какой это?или если это что-то, о чем я не подумал?

Это было полезно?

Решение

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

Обычно, когда вы закрываете/удаляете соединение на уровне библиотек .NET, реальное соединение с сервером базы данных не закрывается.Он просто возвращается в пул соединений внутри поставщика данных и будет повторно использоваться, когда программа запрашивает другое соединение с теми же параметрами и учетными данными.Я не думаю, что сеанс базы данных каким-либо образом сбрасывается перед возвращением в пул, за исключением открытых транзакций и, возможно, некоторых основных параметров.Более дорогие объекты, такие как временные таблицы, остаются в покое.

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

Другие советы

Я почти уверен, что будет вызван метод Connection.Dispose() (и, следовательно, Connection.Close()).

Вы можете убедиться в этом достаточно легко, выполнив 1) и 2) и проверив, что проблема все еще существует.Решение, вероятно, 3), и объяснением будет пул соединений.

Если не произойдет выключение питания или какой-либо другой крайне странный случай, БУДЕТ вызвано удаление.

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

Блок using преобразуется в блок try/catch/finally.Да, он будет удаляться независимо от возврата в блоке использования.

Нет, соединение.Close всегда будет вызываться, потому что внутренне с использованием помещает его в блок try/finally.

Вы также можете рассмотреть возможность создания пула соединений.Попробуйте обернуть свой код в TransactionScope.

Чтобы ответить на ваши вопросы:

  1. Оператор using неявно закрывает соединение при вызове метода Dispose соединения.
  2. Это не должно быть необходимо: http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
  3. Попробуй это.

Оператор using удалит объект, если его класс IDisposable, даже если в блоке using есть оператор return.

Именно пул соединений сохраняет вашу #temptable, поэтому вы можете удалить эту таблицу вручную.

Не зная больше об используемой библиотеке подключений к базе данных, я бы предположил, что это ни одна из первых двух; using был введен специально для того, чтобы упростить очистку таких ресурсов при выходе из методов;это прямой аналог обычного try...finally блок на Java или аналогичный.

Другими словами, return покинет блок и Dispose для соединения будет вызван метод, который, при условии его разумной реализации, должен вызвать метод Close метод как часть этого процесса.

Ключевым моментом здесь является «разумная реализация».

Это вызвано объединением пула соединений.Оберните то, что вы делаете, в транзакцию и откатите ее в конце.Или удалите временную таблицу после заполнения файла ds.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top