2010-07-30 4 views
7

Ho un servizio .Net che si collega ad un database Oracle ad ogni richiesta. Funziona bene all'inizio, ma dopo un certo numero di richieste comincio a ottenere:Oracle.DataAccess.Client.OracleException ORA-03135: connessione persa contatto

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) 
    ... 

Qualche idea di quale potrebbe essere il problema? Dispongo di tutte le connessioni, i risultati e i parametri. Il carico su questo servizio è, beh, molto basso.

+0

solo per curiosità, hai risolto questo problema controllando lo stato della connessione a livello di codice (cioè se già aperto, non fare nulla) OPPURE impostando Validation Connection = true nel web.config, OPPURE entrambi? –

+2

Ciao @Luke, ho "risolto" questo problema a livello personale - ho lasciato il mio lavoro per fare un dottorato :) – Grzenio

+0

hehe congratulazioni, sfortunatamente non posso seguire questa strada, non abbastanza intelligente;) –

risposta

11

Succede perché il codice richiede una connessione da Oracle Connection Pool e il pool di connessioni restituisce una connessione disconnessa/obsoleta con il DB Oracle. ODP.NET non verifica di per sé lo stato della connessione della connessione inviata al client.

Quindi, per essere sicuri, sia di controllare la connection status == Open per il collegamento ricevuto dalla piscina quando si fa un Connection.Open()

O

lasciare ODP.NET fare la verifica per voi impostando Validate Connection = true nella stringa di connessione in web.config.

Entrambi questi metodi hanno un impatto sulle prestazioni poiché verificano lo stato della connessione ogni volta che è necessario connettersi al database.

Una terza opzione che utilizzo è l'utilizzo di eccezioni. Per prima cosa sii ottimista e usa la connessione whateven che viene restituita dal pool di connessioni. Se si ottiene un ORA - 3135, quindi richiedere una nuova connessione ed eseguire nuovamente la query come un ciclo while. Nel migliore dei casi, è possibile ottenere la prima connessione valida e la query verrà eseguita. Nel peggiore dei casi, tutte le connessioni nel tuo pool sono obsolete, nel qual caso il codice verrà eseguito N volte (dove N è la dimensione del pool di connessione).

+0

Ho trovato che l'opzione Convalida connessione è una buona soluzione. Ha aggiunto circa il 20% di spese generali in media per la mia domanda. Sarebbe più alto se si fanno molte domande banali. Inoltre, c'è un po 'di overhead per controllare lo stato della connessione, penso che potrebbe comportare un round-trip al server. Non era più veloce controllare la connessione ogni volta nel codice piuttosto che impostare l'opzione Convalida connessione nella stringa di connessione durante il test. –

+0

Ecco perché non cercare di iniziare. Vai con la connessione che hai. Ottieni una nuova connessione se quella attuale fallisce. – sandyiit

+0

Quando si dice di collocare Validate Connection all'interno della stringa di connessione, si sta parlando all'interno del file ORA o in app.config? – William

2

Ho visto accadere anche questo; prova a disattivare il pool di connessioni con "Pooling = false" nella stringa di connessione. Ho una teoria che le connessioni inattive nel pool scadono, ma ODP.NET non si rende conto che sono scadute, e poi quando la tua app ne prende una e prova a fare qualcosa ottieni quell'eccezione.

+0

Qualcuno ha anche suggerito che questo accada dopo che il database viene rimbalzato. – Grzenio