Закрывает ли ODP.net курсор ссылки при закрытии соединения?
Вопрос
Мне пока не удалось найти нигде явных указаний на это, но я нашел в Интернете множество примеров, отражающих то, что я делал.
У меня есть класс C#, который использует ODP.net для подключения к базе данных Oracle и запуска процедуры, находящейся в пакете.
В моем пакете есть хранимые процедуры, которые принимают выходной параметр курсора ref.Все, что делает процедура, — это открывает курсор для определенного оператора выбора.
Если я выполню эту процедуру непосредственно в базе данных Oracle, то в конечном итоге я получу ошибку максимального количества открытых курсоров.
Итак, мне было интересно, действительно ли ODP.net закрывает этот курсор, открытый в моей процедуре?
Я использую метод OracleDataApaper.Fill(DataSet).
например.
DataSet ds = new DataSet();
OracleConnection conn = new OracleConnection(this.connStr);
OracleCommand com = new OracleCommand("MYPKG.MYQUERY", conn);
OracleDataAdapter adapter = new OracleDataAdapter(com);
conn.Open();
com.Parameters.Add("searchParam", OracleDbType.Varchar2).Value = "myName";
com.Parameters.Add("outCursor", OracleDbType.RefCursor, ParameterDirection.Output);
com.CommandType = CommandType.StoredProcedure;
adapter.Fill(ds);
conn.Close();
PROCEDURE GETALLEMAILS(searchParamIN VARCHAR2, outCursor OUT sys_refcursor) AS
BEGIN
open outCursor
select
EAEMAL as Email
from
EmailTable
where
EmailName = searchParam;
END GETALLEMAILS;
Я просто боюсь оставить открытые курсоры в БД, вот и все.Если кто-нибудь может предоставить ссылки на официальную документацию, это было бы здорово!
Обновления:
Спасибо за вклад.я звонил
com.Dispose();
conn.Close();
conn.Dispose();
но исключил их из своего примера.
Я нашел это сообщение на форуме, в котором говорится, что метод OracleDataAdapter.Fill(Dataset) освобождает курсор ссылки после выполнения метода Fill().
http://www.frontoracle.com/oracle-archive/140/386140-close-ref-cursor.html
Однако мне бы хотелось, чтобы документация Oracle более подробно описывала этот процесс.
Решение
ODP.NET требует от вас навести порядок.Так что вы:
- приходится удалять экземпляры OracleParameter, поскольку они содержат неуправляемые ресурсы (!), а Odp.net этого не делает.
- приходится удалять объекты OracleCommand, поскольку они тоже содержат неуправляемые ресурсы, и закрытие соединения не закрывает их.
- открытые курсоры не могут жить без открытого соединения, хотя в odp.net ничего не очищается после закрытия соединения (или его удаления), поэтому вам придется очистить и их (и, конечно, до закрытия соединения).
И.о.в.:очистите то, что вы создаете.
Возможно, OracleDataAdapter уже делает это за вас, но это неясно (и в документах odp.net этого не говорится, поэтому вам нужно проверить (нечитаемый) код с помощью рефлектора, чтобы убедиться в этом.Хотя практическое правило с odp.net:чтобы избежать утечек памяти, всегда вызывайте Dispose для всего по порядку:параметр, курсор, команда, транзакция, соединение.
Другие советы
Я не уверен, что вы наткнулись на этот статья, и она не имеет прямого отношения к вашему вопросу, но иллюстрирует то, что я узнал при работе с ODP.Net:в случае сомнений всегда закрывайте (соединения) и утилизируйте.Каждый метод, который я пишу, который использует экземпляр ODP-соединений, команд и/или курсоров, имеет предложениеfinally, удаляющее все.