2016-04-20 6 views
0

Ich verwende Oracle über ihre offiziell verwalteten Treiber für .NET (ein Nuget-Paket).Wie behandelt man Datenbankausnahmen in .NET?

Meine Anwendung verwendet von Anfang an dieselbe Verbindung zur Datenbank und wird von mehreren Standorten aus zur Abfrage verwendet.

In einigen Fällen gibt es möglicherweise Verbindungs ​​"Schluckauf", die Ausnahmen verursachen. Das Problem ist, dass ich nicht weiß, was die beste Strategie ist, um eine Abfrage erneut zu versuchen, wenn dies geschieht.

Gibt es einen gemeinsamen Weg, um diese Situation zu lösen?

Vielen Dank.

+1

Das ist ziemlich breit, aber warum verwenden Sie eine einzelne Verbindung, warum nicht mehrere Verbindungen verwenden und Verbindung so spät wie möglich öffnen und so früh wie möglich schließen. – Habib

Antwort

1

Ich stimme dem Kommentar von Habib zu.

Das Oracle .NET-Paket verwendet Verbindungspooling. Selbst wenn Sie mehrere Verbindungen öffnen, werden diese entsprechend verwaltet, sodass Sie sie nicht offen halten müssen.

Das bedeutet, dass der Code vereinfacht werden kann, in so etwas wie dieser Pseudo-Code:

using(OracleConnection conn = MakeConnection()) 
{ 
    //do stuff with connection 

    //not necessary, but I always manually close connection. Doesn't hurt. 
    conn.Close(); 
} 

Wenn Sie Verbindungsprobleme unsicher sind auch in diesen kleinen eine Ausführung, können Sie es in einem wickeln Try-catch-Block wie folgt:

try 
{ 
    using(OracleConnection conn = MakeConnection()) 
    { 
     //do stuff with connection 

     //not necessary, but I always manually close connection. Doesn't hurt. 
     conn.Close(); 
    } 
} 
catch(OracleException ex) 
{ 
    //handle exception. 
} 

OracleException die wichtigste Ausnahme mit dem .NET oracle-Paket sein aussieht. Bitte beachten Sie, dass es andere geben kann, die Sie genauer erfassen möchten.

+0

'Using' Block wird Connection.Close() und Connection.Dispose() normalerweise auch im Falle von Ausnahmen behandeln. Wir müssen es nicht im Code angeben. – Gokul

1

Es wäre einfacher, die Verbindung im laufenden Betrieb zu erstellen, wenn die Abfrage durchgeführt wird. Ich glaube nicht, dass Ihnen ein einfacher try/catch dabei helfen würde, denn selbst wenn Sie die Verbindung im catch-Block neu initialisiert haben, müssten Sie Ihre Abfrage irgendwie erneut ausführen.

Ich empfehle dies nicht, aber man könnte eine Retry-Klasse verwenden, die die Verbindung neu initialisiert, wenn eine Ausnahme gefangen ....

public class Retry 
{ 
    public static void Do(Action action, TimeSpan retryInterval, int retryCount = 3) 
    { 
     Do<object>(() => 
     { 
      action(); 
      return null; 
     }, 
     retryInterval, retryCount); 
    } 

    public static T Do<T>(Func<T> action, TimeSpan retryInterval, int retryCount = 3) 
    { 
     var exceptions = new List<Exception>(); 

     for (int retry = 0; retry < retryCount; retry++) 
     { 
      try 
      { 
       if (retry > 0) 
        Thread.Sleep(retryInterval); 
       return action(); 
      } 
      catch (ConnectionException ex) 
      { 
       // ***Handle the reconnection in here*** 

       exceptions.Add(ex); 
      } 
     } 

     throw new AggregateException(exceptions); 
    } 
} 

Dann können Sie Ihre Anfrage nennen wie

Retry.Do(() => MyQueryMethod, TimeSpan.FromSeconds(5)); 

Ich habe die Basis für diesen Retry-Code von SO vor langer Zeit, erinnere mich nicht an den Thread, aber es ist nicht mein ursprünglicher Code. Ich habe es für einige Dinge jedoch ziemlich oft benutzt.