2008-09-27 17 views
7

Tengo una aplicación que está causando muchos dolores de cabeza. Es una aplicación .NET que se conecta a SQL Server 2005 a través de un servicio web. El programa tiene una grilla que se llena con un procedimiento almacenado de larga ejecución que tiende a agotar el tiempo de espera. En el caso en que se agote el tiempo de espera y se genere una SqlException, no hay manejo de la excepción para cerrar la conexión.¿Cuáles son las consecuencias de no cerrar la conexión de la base de datos después de un error?

¿Cuáles son las consecuencias reales de esta condición? Creo que el framework o SQL Server probablemente lo solucione de una manera u otra, pero no estoy seguro.

Adición El programa siempre funciona bien por la mañana, pero después de aproximadamente una hora de uso, básicamente deja de funcionar. El problema no es que no sepa cómo codificar la conexión correctamente. Necesito saber si estos síntomas podrían ser causados ​​por las conexiones no cerradas. Es una gran cosa cambiar el código de producción y me gustaría saber que al menos es posible que este sea el problema.

Conclusión Diseñé este error en cientos de conexiones simultáneas. Nunca pude reproducir la condición de falla en el entorno de la aplicación. Las mejores prácticas marcadas responden como correctas. Gracias a todos.

+0

Creo que la etiqueta debería haber sido sql-server y no dos etiquetas separadas, ya que las preguntas muestran –

+0

. gracias. –

+0

Parece que tiene la agrupación de conexiones activada en su entorno de producción. Con la agrupación activada, las conexiones no se cierran incluso si les dices que se cierren, por lo que no importará que no las cierre. – MusiGenesis

Respuesta

6

Desde un SqlConnection se cierra, mientras que la eliminación que suelen utilizar esta sintaxis

using (SqlConnection conn = new SqlConnection()) 
{ 
    // SqlCode here 
} 
2

Hay un límite de conexión; si su aplicación se cuelga con frecuencia y no cierra las conexiones automáticamente, se denegarán las nuevas solicitudes de conexión.

Dicho esto, las conexiones se agotan después de un tiempo si no están cerradas.

0

Puede que se queden sin conexiones disponibles si sucede con bastante frecuencia, debe usar finalmente todas las veces que ejecute un comando para cerrar la conexión.

0

El recolector de basura eventualmente finalizará su objeto de conexión abierta, pero no sabe cuándo volverá a aparecer el GC la próxima vez. Hasta entonces, es posible que se quede sin conexiones en su grupo si tiene mucho tráfico o si se trata de un servidor SQL compartido.

¿Por qué no eliminarlo en la sección final de su bloque try/catch?

finally 
{ 
    if (cn != null) 
    { 
     cn.Dispose(); 
     cn = null; 
    } 
} 

Esto debe hacerse en el método de servicio web obviamente.

+0

que se hace automáticamente en un bloque que usa –

+0

Cierto, pero obviamente él "no usa" ni ... – Codewerks

+0

¿Por qué votar una respuesta correcta? No entiendo ... – Codewerks

0
try 
{ 
    sqlCommandObject.Execute(); // this line will throw a timeout exception 
} 
finally 
{ 
    sqlConnectionObject.Close(); // this will execute no matter what happens 
} 
+0

Creo que la recomendación de MS y otros fue utilizar Dispose() o, como señaló Pablo, usar un bloque. Dispose() llama a Close() en el objeto de conexión y realiza otra limpieza si es necesario. – Codewerks

+0

Esta respuesta es "correcta". http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx "Cerrar y eliminar son funcionalmente equivalentes". –

1

Si la aplicación deja de funcionar después de una hora más o menos, eso podría deberse a que las conexiones no se cierren o desechen.

1

Esta es la razón por la '' usando la palabra clave es tan importante cuando se utiliza ADO.Net

using (SqlConnection conn = new SqlConnection()) 
{ 
    ... 
} 

Esto obliga a un tipo de recopilación de basura determinística en el objeto ADO.Net utilizando la interfaz IDispose.

La mayoría del código de la base de datos utiliza una gran cantidad de cláusulas 'usando' anidadas para tal fin.

+0

La interfaz IDispose no tiene nada que ver con la recolección de basura. Obliga a la liberación determinística de recursos no administrados. – Joe

+0

Joe, su afirmación es incorrecta. IDispose no tiene nada que ver con recursos no administrados. Consulte http://www.codeproject.com/KB/mcpp/garbage_collection.aspx, por ejemplo. – kervin

Cuestiones relacionadas