2008-12-11 17 views
5

No he podido encontrar esto explícitamente en ninguna parte todavía, pero un montón de ejemplos que he encontrado en línea siguen lo que he estado haciendo.¿ODP.net cierra un cursor de ref cuando se cierra la conexión?

Tengo una clase C# que usa ODP.net para conectarse a un Oracle DB y ejecutar un procedimiento que está en un paquete.

Mi paquete tiene procedimientos almacenados que toman un parámetro de salida del cursor de referencia. Todo lo que hace el procedimiento es abrir el cursor para una instrucción select particular.

Si ejecuto este procedimiento directamente en el oráculo db, entonces eventualmente alcanzaré un número máximo de errores de cursores abiertos.

Entonces, me preguntaba si ODP.net cierra este cursor que se abrió en mi procedimiento.

Estoy usando el método OracleDataApaper.Fill (DataSet).

por ejemplo.

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; 

Solo tengo miedo de dejar abiertos los cursores en la base de datos, eso es todo. Si alguien puede proporcionar enlaces a la documentación oficial, ¡sería genial!


actualizaciones:

Gracias por la entrada. Estaba llamando a

com.Dispose(); 
conn.Close(); 
conn.Dispose(); 

pero los dejé fuera de mi ejemplo.

Encontré esta publicación en el foro, que indica que el método OracleDataAdapter.Fill (Dataset) libera el cursor ref después de que se haya ejecutado el método Fill().
http://www.frontoracle.com/oracle-archive/140/386140-close-ref-cursor.html

deseo la documentación de Oracle fue más explícito en la descripción de este proceso sin embargo.

Respuesta

9

ODP.NET requiere que limpie las cosas. Así que:

  • tienen que disponer casos OracleParameter, ya que contienen recursos no administrados y Odp.net no hace esto
  • tienen que disponer OracleCommand objetos, ya que ellos también contienen recursos no administrados y cierre de una (!) la conexión no cierra estos
  • los cursores abiertos no pueden vivir sin una conexión abierta, aunque en odp.net nada se limpia después de que se cierra una conexión (o se desecha), por lo que debe limpiarlos también (y antes) la conexión se cierra, por supuesto).

I.o.w .: limpia lo que creas.

Puede ser que OracleDataAdapter ya lo haga por usted, pero eso no está claro (y los documentos de odp.net no dicen esto, por lo que debe verificar el código (ilegible) con reflector para asegurarse. de pulgar con odp.net: para evitar fugas de memoria, siempre llame a disponer, en todo en el orden: parámetro, cursor, comando, transacción, conexión.

+2

Agregaría OracleDataReader a la lista de objetos para eliminar, si usa ellos. Parece que ha resuelto nuestro problema de "máximo cursores abiertos". – Fueled

0

No estoy seguro de si ha tropezado con el artículo this, y no se aplica directamente a su pregunta, pero ilustra algo que aprendí al trabajar con ODP.Net: en caso de duda, siempre cerca (conexiones) y deseche. Cada método que escribo que usa una instancia de conexiones ODP, comandos y/o cursores tiene una cláusula final que elimina todo.

Cuestiones relacionadas