2010-07-30 48 views
7

Tengo un servicio .Net que se conecta a una base de datos Oracle en cada solicitud. Funciona bien al principio, pero después de un número de solicitudes empiezo a obtener:Oracle.DataAccess.Client.OracleException ORA-03135: contacto perdido de conexión

Oracle.DataAccess.Client.OracleException ORA-03135: connection lost contact 
    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure) 
    at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src) 
    at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior) 
    at Oracle.DataAccess.Client.OracleCommand.ExecuteReader() 
    at MyApp.Services.OracleConnectionWithRetry.ExecuteReader(OracleCommand command) 
    ... 

¿Alguna idea de cuál podría ser el problema? Dispongo de todas las conexiones, resultados y parámetros. La carga en este servicio es, bueno, muy baja.

+0

solo por curiosidad, resolvió este problema al verificar el estado de la conexión mediante programación (es decir, si ya está abierto, no hacer nada) O establecer Validación Conexión = verdadero en el web.config, O ambos? –

+2

Hola @Luke, "resolví" este problema a nivel personal. Dejé mi trabajo para hacer un doctorado :) – Grzenio

+0

jeje felicidades, desafortunadamente no puedo seguir ese camino, no soy lo suficientemente inteligente;) –

Respuesta

11

Ocurre porque el código solicita una conexión del conjunto de conexiones Oracle y el grupo de conexiones devuelve una conexión desconectada/obsoleta a Oracle DB. ODP.NET no prueba por sí mismo el estado de conexión de la conexión enviada al cliente.

Así que para estar seguro, ya sea que marque la connection status == Open para la conexión recibida desde la piscina cuando se hace una Connection.Open()

O

dejar que ODP.NET hacer la comprobación de que mediante el establecimiento de Validate Connection = true en su cadena de conexión en web.config.

Ambos métodos tienen un impacto en el rendimiento ya que prueban el estado de la conexión cada vez que necesita conectarse a la base de datos.

Una tercera opción que uso es el uso de excepciones. Primero sea optimista y use la conexión de Whateven devuelta desde el grupo de conexiones. Si obtiene un ORA - 3135, solicite una nueva conexión y ejecute su consulta nuevamente como un ciclo while. En el mejor de los casos, puede obtener su primera conexión como válida y su consulta se ejecutará. En el peor de los casos, todas las conexiones de su grupo están obsoletas, en cuyo caso el código se ejecutará en tiempo N (donde N es el tamaño del grupo de conexiones).

+0

Encontré que la opción Validar conexión es una buena solución. Agregó aproximadamente un 20% de sobrecarga en promedio para mi aplicación. Sin embargo, sería más importante si haces muchas consultas triviales. Además, hay un poco de sobrecarga para verificar el estado de la conexión, creo que podría implicar un viaje de ida y vuelta al servidor. No fue más rápido verificar la conexión cada vez en el código que simplemente establecer la opción Validar conexión en la cadena de conexión en mi prueba. –

+0

Es por eso que se abstengan de verificar para empezar. Ve con la conexión que tienes. Obtenga una nueva conexión si la actual falla. – sandyiit

+0

Cuando dice colocar Validate Connection dentro de la cadena de conexión, ¿está hablando dentro del archivo ORA o en app.config? – William

2

He visto esto suceder también; intente desactivar la agrupación de conexiones con "Pooling = false" en la cadena de conexión. Tengo una teoría de que las conexiones inactivas en el grupo caducan, pero ODP.NET no se da cuenta de que han expirado, y luego, cuando su aplicación toma una e intenta hacer algo, obtiene esa excepción.

+0

Alguien también sugirió que esto ocurra después de que la base de datos se recupere. – Grzenio