2010-07-30 8 views
7

Ich habe einen .Net-Dienst, der bei jeder Anforderung eine Verbindung zu einer Oracle-Datenbank herstellt. Es funktioniert am Anfang in Ordnung, aber nach einer Anzahl von Anfragen, die ich anfangen,:Oracle.DataAccess.Client.OracleException ORA-03135: Verbindung verlorener Kontakt

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

Jede Idee, was das Problem sein könnte? Ich verfüge über alle Verbindungen, Ergebnisse und Parameter. Die Belastung für diesen Service ist, naja, sehr gering.

+0

nur aus Neugierde, lösten Sie dieses Problem mit der Überprüfung des Verbindungsstatus programmgesteuert (d. H., Wenn bereits geöffnet, nichts tun) ODER Einstellung Validation Connection = True in der web.config ODER beide? –

+2

Hallo @Luke, ich "löste" dieses Problem auf einer persönlichen Ebene - ich kündigte meinen Job, um eine Doktorarbeit zu machen :) – Grzenio

+0

hehe Herzlichen Glückwunsch, leider kann ich nicht diesen Weg gehen, nicht schlau genug;) –

Antwort

11

Dies passiert, weil Ihr Code eine Verbindung vom Oracle-Verbindungspool anfordert und der Verbindungspool eine Verbindung zu der Oracle-Datenbank zurückgibt. ODP.NET prüft nicht selbst den Verbindungsstatus der an den Client gesendeten Verbindung.

So sicher sein, entweder Sie die connection status == Open für die aus dem Pool erhalten Verbindung überprüfen, wenn Sie eine Connection.Open()

OR

lassen ODP.NET tun für Sie tun die Überprüfung durch Einstellen Validate Connection = true in Ihrer Verbindungszeichenfolge in web.config.

Diese beiden Methoden haben Auswirkungen auf die Leistung, da sie den Verbindungsstatus jedes Mal testen, wenn Sie eine Verbindung zur Datenbank herstellen müssen.

Eine dritte Option, die ich verwende, ist die Verwendung von Ausnahmen. Seien Sie zuerst optimistisch und verwenden Sie whateven Verbindung wird aus dem Verbindungspool zurückgegeben. Wenn Sie einen ORA-3135 erhalten, fordern Sie eine neue Verbindung an und führen Sie Ihre Abfrage wie eine While-Schleife erneut aus. Im besten Fall erhalten Sie Ihre erste Verbindung als gültig und Ihre Anfrage wird ausgeführt. Im schlimmsten Fall sind alle Verbindungen in Ihrem Pool veraltet. In diesem Fall wird der Code N Mal ausgeführt (wobei N die Größe des Verbindungspools ist).

+0

Ich fand die Option Verbindung validieren als eine gute Lösung. Es hat durchschnittlich 20% Overhead für meine Anwendung hinzugefügt. Es wäre jedoch höher, wenn Sie viele triviale Abfragen durchführen. Außerdem gibt es einen gewissen Aufwand, um den Verbindungsstatus zu überprüfen, ich denke, es könnte einen Hin- und Rückweg zum Server beinhalten. Es war nicht schneller, die Verbindung jedes Mal im Code zu überprüfen, als nur die Option Verbindung validieren in der Verbindungszeichenfolge in meinem Test festzulegen. –

+0

Das ist der Grund, warum man nicht mit der Überprüfung beginnt. Geh mit der Verbindung, die du hast. Erhalten Sie eine neue Verbindung, wenn die aktuelle fehlschlägt. – sandyiit

+0

Wenn Sie sagen, die Verbindung in die Verbindungszeichenfolge zu stellen, sprechen Sie in der ORA-Datei oder in app.config? – William

2

Ich habe gesehen, dass das auch passiert; Versuchen Sie, Verbindungspooling mit "Pooling = false" in der Verbindungszeichenfolge zu deaktivieren. Ich habe eine Theorie, dass inaktive Verbindungen im Pool ablaufen, aber ODP.NET erkennt nicht, dass sie abgelaufen sind, und wenn Ihre App dann eine greift und versucht, etwas zu tun, erhalten Sie diese Ausnahme.

+0

Jemand hat auch vorgeschlagen, dass dies passiert, nachdem die Datenbank abgeprallt ist. – Grzenio