none
Mit MsSql-Server erreichbar oder nicht ? RRS feed

  • Frage

  • Hallo,

    ich habe ein MsSql-Server und versuche über ein VS 2010, C#, ClientApp eine Verbindung aufbauen, was auch problemlos klappt.

    Nun versuche ich über einen Timer alle 30sek nachzuschauen, ob der Server erreichbar ist, indem ich den LAN-Stecker herausziehe/einstecke. Ich habe dafür eine Fkt geschrieben:

    public Boolean MsSql_Conn_Check()
    {
     Boolean bDa = false;
     try
     {
       using (conMsSql = new SqlConnection(@"Data Source=sServer; Database=DB; User Id=test; Password=test; Connect Timeout=15"))
       {
         conMsSql.Open();  // Öfnen
         if (conMsSql.State == ConnectionState.Open) bDa = true;
       }
     }
     catch (Exception ex)
     {
       bDa = false;
     }
     finally
     {
      conMsSql.Close();
     }
     return(bDa);
    }

    Feststellung: LAN-Stecker herausziehen dauert ca 45sek und beim LAN-Stecken ca 15sek bis er mitbekommt.

    Frage: wie/wo kann ich an den Parameters drehen, daß er so schnell wie möglich dies mitbekommt ?

    MFG

     
    Donnerstag, 10. Juli 2014 07:00

Antworten

  • Hallo zusammen,

    Eine Verbindung ist nach außen hin immer nur Open oder Closed.

    Ein Open reicht aus, um zu erkennen, ob eine Verbindung aktiv ist. Denn selbst wenn es aus einem Connection Pool kommt, wird ein intern die Verbindung zurückgesetzt (sp_resetconnection), und dabei der Server kontaktiert.

    Der Status Broken existiert zwar seit .NET 1.0, ist aber nicht implementiert. Eine "kaputte" Verbindung kann (logisch) im Connection Pool existieren. Dies wird aber erkannt und beim erneuten Öffnen versucht, eine neue aufzubauen. Wenn das fehlschlägt, gibt es eine Ausnahme vom Typ SqlException, die man behandeln sollte[1].

    Bricht eine offene Verbindung ab, so wird die ausgeführte Anweisung - eine der SqlExecuteXYZ Methoden - durch eine SqlException beendet. Auf den Zustand der Verbindung sollte man sich danach nicht mehr verlassen.

    Im weiteren sollte man sich als Datenbank-Entwickler auf die Implementation von Transaktionen konzentrieren. Das war immer (und wird immer) das Mittel sein, nur vollständige (saubere) Daten bei der Datenbank abzuliefern.

    Jede weitere Fehlerbehandlung ist komplex - das Word Dokument im oben verlinkten Artikel sollte dem Interessierten ein Verständnis davon geben, was alles berücksichtigt werden muss. Aber man kann auch nachlesen, das dafür Grenzen gibt.

    Ohne SQL Server Hilfe ist es nicht sauber implementierbar, weswegen es auch erst ab SQL Server 2014  im .NET (und ODBC) Treiber vorhanden ist. (OleDb  ist veraltet, da wird nichts kommen).

    Gruß Elmar

    [1] Man sollte nur die SqlException behandeln, andere Ausnahmen (z. B. InvalidOperationException) weisen auf einen Programmier- / Konfigurations-Fehler hin. Der muss behoben werden - und sollte nicht durch eine (falsche) Fehlermeldung verdeckt werden.

    • Als Antwort markiert ati.sah Montag, 4. August 2014 06:08
    Donnerstag, 10. Juli 2014 19:53
    Beantworter

Alle Antworten

  • Frage: wie/wo kann ich an den Parameters drehen, daß er so schnell wie möglich dies mitbekommt ?


    Am SqlConnection.ConnectionTimeout Property, das steht per Default auf 15 Sekunden.

    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    Donnerstag, 10. Juli 2014 07:27
  • Hallo,

    wie Olaf schon schreibt, dauert es durch den Connect Timeout von 15 Sekunden schon mal mindestens solange bis eine fehlende Verbindung bemerkt wird.

    Aber einen Timer laufen zu lassen, der das alle 30 Sekunden tut, ist sinnfrei, denn am Ende wird es nichts nützen, sondern nur unnötige Ressourcen verbraten.

    Nicht nur nach Murphys Gesetz passieren solche Unterbrechungen, wenn man sie am wenigsten gebrauchen kann. Also z. B. wenn eine echte Aktivität wie ein Datenabruf oder -aktualisierung stattfindet. Und das ist nur durch eine vollständige Fehlerhandlung an betreffender Stelle zu regeln.

    Deswegen: Beschränke den Test auf einen einmaligen zu Programmstart und später nur auf Anforderung.

    Gruß Elmar

    Donnerstag, 10. Juli 2014 07:52
    Beantworter
  • Hallo,

    ich will dabei in Statuszeile dadurch eine Ausgabe machen, daß der User merkt jetzt gibt es keine Verbindung zum Server.

    Frage: wie ist so eine Lösung möglich, daß er autom merkt Server verfügbar/nichtverfügbar (bitte Sorcecode) ?

    MFG

    Donnerstag, 10. Juli 2014 08:11
  • Hallo,

    "testen" kann man eine Verbindung zu einem (SQL) Server nur, in dem man sie benutzt. Und insofern zeigt Dein Code den Weg. Nur hat eine "Status-Information" keinen Wert, da sie nichts über die Zuverlässigkeit während der Verwendung aussagt.

    In einem lokalen Netzwerk wird man i. a. nur selten Verbindungsprobleme haben - da reicht ein "Test" am Anfang.

    Über eine WAN-Verbindung (wie dem Internet) kann jederzeit was passieren. Da das Thema mit Cloud Lösungen wie Windows Azure wichtiger geworden ist, findet man in .NET 4.5 Erweiterungen, die mit unterbrochenen Verbindungen umgehen können siehe dazu:

    Idle Connection Resiliency

    bzw. in Kurzform im Blog Artikel der Abschnitt ADO.NET idle connection resiliency

    Alles das kann eine "Status-Anzeige" nicht leisten - es ist IMO ein Non-Feature, die falsche Informationen (Sicherheit) vorgaukeln kann.

    Gruß Elmar

    Donnerstag, 10. Juli 2014 16:27
    Beantworter
  • Also ich halte, wie Elmar, auch nichts davon ständig die Connection testen zu wollen. Wenn man ein Statement ausführen will, lässt man es darauf ankommen und sieht zu, ein vernünftiges Exception Handling zu haben; es z.B. 3 weitere Male zu versuchen und dann ggf. den User über den Fehler zu informieren. Und wann die Verbindung wieder verfügbar sein wird, kann eh keiner vorhersagen.

    Aber wegen Cloud Lösungen gibt es mittlerweile als weitere Klasse die ReliableSqlConnection Class, die bei Verbindungsverlust versucht, diese automatisch wieder aufzubauen. Habe ich noch nie verwendet, hört sich aber gut an. 


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Donnerstag, 10. Juli 2014 18:02
  • Hi,

    ständig den Connection State zu überwachen finde ich auch nicht gut...

    Eine Möglichkeit die ich praktiziere (sicher werden da auch einige sagen das geht

    auf die Performance...) ist das ich entweder bei Select,Insert oder Update einen

    Connection Check mache mit einem Select Count auf eine Hilfstabelle bspw. mit nur einem Datensatz oder

    fragst einfach vor jedem Zugriff auf die DB den Connection State ab. Ist dieser nicht Open oder

    Broken oder Closed versuche ich einen erneuten Connect (2 oder 3 mal), erst wenn diese dann Fehl schlagen

    erzeuge oder zeige ich eine Exception an.

    Wie oben schon erwähnt kann man das mit einer Fehlerbehandlung ganz gut abfangen.

    Gruß

    Jens

    Donnerstag, 10. Juli 2014 19:06
  • Hallo zusammen,

    Eine Verbindung ist nach außen hin immer nur Open oder Closed.

    Ein Open reicht aus, um zu erkennen, ob eine Verbindung aktiv ist. Denn selbst wenn es aus einem Connection Pool kommt, wird ein intern die Verbindung zurückgesetzt (sp_resetconnection), und dabei der Server kontaktiert.

    Der Status Broken existiert zwar seit .NET 1.0, ist aber nicht implementiert. Eine "kaputte" Verbindung kann (logisch) im Connection Pool existieren. Dies wird aber erkannt und beim erneuten Öffnen versucht, eine neue aufzubauen. Wenn das fehlschlägt, gibt es eine Ausnahme vom Typ SqlException, die man behandeln sollte[1].

    Bricht eine offene Verbindung ab, so wird die ausgeführte Anweisung - eine der SqlExecuteXYZ Methoden - durch eine SqlException beendet. Auf den Zustand der Verbindung sollte man sich danach nicht mehr verlassen.

    Im weiteren sollte man sich als Datenbank-Entwickler auf die Implementation von Transaktionen konzentrieren. Das war immer (und wird immer) das Mittel sein, nur vollständige (saubere) Daten bei der Datenbank abzuliefern.

    Jede weitere Fehlerbehandlung ist komplex - das Word Dokument im oben verlinkten Artikel sollte dem Interessierten ein Verständnis davon geben, was alles berücksichtigt werden muss. Aber man kann auch nachlesen, das dafür Grenzen gibt.

    Ohne SQL Server Hilfe ist es nicht sauber implementierbar, weswegen es auch erst ab SQL Server 2014  im .NET (und ODBC) Treiber vorhanden ist. (OleDb  ist veraltet, da wird nichts kommen).

    Gruß Elmar

    [1] Man sollte nur die SqlException behandeln, andere Ausnahmen (z. B. InvalidOperationException) weisen auf einen Programmier- / Konfigurations-Fehler hin. Der muss behoben werden - und sollte nicht durch eine (falsche) Fehlermeldung verdeckt werden.

    • Als Antwort markiert ati.sah Montag, 4. August 2014 06:08
    Donnerstag, 10. Juli 2014 19:53
    Beantworter