¿Puede una instrucción de retorno evitar que una declaración de cierre utilizando una conexión a una base de datos?

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

Pregunta

Cuando estoy creando tablas temporales consigo un mensaje de error que me dice que la tabla temporal ya existe. La tabla temporal es única para la sesión por lo que parece que mi conexión no se cierra correctamente y creo que puede tener algo que ver con una instrucción de retorno que tengo en la instrucción using.

Tengo el siguiente código:

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

Yo uso este tipo de código en varios lugares para crear una tabla temporal con el mismo nombre.

Por desgracia, estoy recibiendo el siguiente error: There is already an object named '#MyTempTable' in the database

.

Ahora, sé que la tabla temporal es única para la sesión y lo que una vez se cierra la sesión que debe desaparecer.

Hay tres cosas que creo que podría causar este ...

  1. Necesito llamar Connection.close ()
  2. necesito para colocar la instrucción de retorno fuera de mi instrucción using
  3. Necesito eliminar la tabla temporal creé antes de devolver

¿Alguien sabe cuál es? o si es algo que no he pensado?

¿Fue útil?

Solución

Estoy adivinando aquí, pero verifica la configuracion de conexión de la puesta en común de bases de datos. Prueba a activar la puesta en común fuera y ver si ayuda.

Por lo general, cuando se cierra / disponer de conexión en el nivel de las bibliotecas .NET, conexión con el servidor de base de datos real no es cerrado. Sólo se devuelve a la agrupación de conexiones en el interior proveedor de datos y se volverá a utilizar cuando el programa pide otra conexión con los mismos parámetros y credenciales. No creo que la base de datos se restablece la sesión de ninguna manera antes de ser devuelta a la piscina, a excepción de las transacciones abiertas y tal vez algunos parámetros básicos. los objetos más caros, al igual que las tablas temporales, se quedan solos.

Puede activar la puesta en común fuera (muy ineficiente). O se puede comprobar la existencia tabla temporal antes de intentar crear y borrar su contenido, si existe. O bien, puede eliminar la tabla temporal antes de cerrar la conexión.

Otros consejos

Estoy bastante seguro de que connection.Dispose () (y por lo tanto Connection.close () también) serán llamados.

Puede verificar que con bastante facilidad haciendo 1) y 2) y comprobar que aún existe el problema. La solución es, probablemente, 3) y la explicación sería agrupación de conexiones.

A menos que se produzca un ciclo de encendido o de alguna otra esquina disponer caso serio extraño se llamará.

Si quieres una prueba envolver el objeto y poner un punto de interrupción en.

Un bloque usando se traduce en un try / catch / bloque finally bajo el capó. Sí, va a disponer independientemente de la rentabilidad en el uso de bloque.

No, Connection.close siempre se llamará, porque internamente usando pone en un try / finally.

También es posible que desee considerar la agrupación de conexiones. Trate de envolver su código en un TransactionScope.

Para responder a sus preguntas:

  1. La instrucción using cerrará la conexión implícita, cuando se llama al método Dispose de la conexión.
  2. No debería ser necesario: http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
  3. Inténtelo.

using va a disponer el objeto si su clase es IDisposable incluso hay una instrucción de retorno en el uso de bloque.

Es la agrupación de conexiones que mantiene su #temptable, es posible que desee dejar esa tabla manualmente.

Sin saber más acerca de la biblioteca de conexión de base de datos en uso, supongo que es ninguno de los dos primeros; using se introdujo específicamente para hacer la limpieza de dichos recursos más fácil al regresar de métodos; que es directamente análoga a un bloque de try...finally ordinaria en Java o similar.

En otras palabras, el return dejará el bloque y el método Dispose serán llamados en la conexión, lo que debería, asumiendo una aplicación sensata de los mismos, llame al método Close como parte de ese proceso.

El punto clave aquí es "la aplicación en su sano juicio".

Se trata de ser causada por la agrupación de conexiones. Envuelva lo que está haciendo en una transacción, y rodar hacia atrás al final. O bien, eliminar la tabla temporal después de poblar el DS.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top