none
Problem mit TimeOut bei ODBC-Verbindung RRS feed

  • Frage

  • Hallo,

     

    ich habe zur Zeit einige Probleme mit einer Anwendung (.NET), die auf einem SQL-Server 2005 Standard daten von einer DB in eine andere Schreiben soll. Dabei werden schon recht große Datenmengen übertragen und es kommt regelmäßig zu Fehlern wegen timeout:

     

    System.Data.OleDb.OleDbException: Timeout abgelaufen
     bei System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
     bei System.Data.OleDb.OleDbCommand.ExecuteNonQuery()
     bei copy_E3_to_DWH.Program.Copy_RunData()
    
    

     

    Ich gebe innerhalb der Anwendung einen TimeOut von 3000s an.

     

    "Provider=SQLOLEDB.1;Password=pw;Persist Security Info=True;User ID=user;Initial Catalog=database;Data Source=datsource;Connect Timeout=3000;"
    
    

    Innerhalb des SQLServers gebe ich den "Timeout für Remoteanwendungen" mit 6000 an.

    Trotzdem bekomme ich innerhalb von wenigen Minuten die Fehlermeldung mit dem Timeout. Es kann schon mal sein, dass die Abfrage über 10min  läuft, aber normalerweise sollte doch deswegen kein Timeout kommen oder?

    An welcher Stelle kann denn noch ein Wert für den Timeout eingestellt werden?

     

    Gruß Rico

     

    Dienstag, 7. Dezember 2010 09:13

Antworten

  • Hallo Rico,

    Dafür der OleDbCommand.CommandTimeout Parameter zuständig,
    im Standard wären das 30 Sekunden, setzt Du ihn auf 0 wird endlos gewartet
    (naja, oder bis der Anwender das Programm abbricht ;-)

    Der Connect Timeout Parameter legt nur fest, wie lange auf den Verbindungsaufbau
    gewartet wird, für die Befehlsausführung hat er keine Bedeutung.
    Und auch den RemoteTimeout solltest Du ihn Ruhe lassen, der regelt die Einstellung für Verbindungsserver.

    Wenn es sich bei beiden Datenbank um eine SQL Server DAtenbank handelt,
    wäre der Einsatz des SqlClients von SqlBulkCopy u. U. eine schnellere Variante.
    Das hängt aber vom spezifischen Szenario ab.

    Gruß Elmar

    • Als Antwort markiert Rico Fiedler Dienstag, 7. Dezember 2010 10:22
    Dienstag, 7. Dezember 2010 09:32
    Beantworter
  • Hallo Rico,

    der Parameter "Connect Timeout" bestimmt, wann es beim Anmeldevorgang es zum Timeout kommt, wenn z.B. der Server nicht erreichbar ist.

    Es gibt noch beim OleDbCommand das Property CommandTimeout, das Du setzen kannst.

    Warum verwendest Du überhaupt OleDB Klassen, es gibt auch den SqlClient der optimaler für den Zugriff auf den SQL Server ist?


    Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de
    • Als Antwort markiert Rico Fiedler Dienstag, 7. Dezember 2010 10:23
    Dienstag, 7. Dezember 2010 09:37

Alle Antworten

  • Hallo Rico,

    Dafür der OleDbCommand.CommandTimeout Parameter zuständig,
    im Standard wären das 30 Sekunden, setzt Du ihn auf 0 wird endlos gewartet
    (naja, oder bis der Anwender das Programm abbricht ;-)

    Der Connect Timeout Parameter legt nur fest, wie lange auf den Verbindungsaufbau
    gewartet wird, für die Befehlsausführung hat er keine Bedeutung.
    Und auch den RemoteTimeout solltest Du ihn Ruhe lassen, der regelt die Einstellung für Verbindungsserver.

    Wenn es sich bei beiden Datenbank um eine SQL Server DAtenbank handelt,
    wäre der Einsatz des SqlClients von SqlBulkCopy u. U. eine schnellere Variante.
    Das hängt aber vom spezifischen Szenario ab.

    Gruß Elmar

    • Als Antwort markiert Rico Fiedler Dienstag, 7. Dezember 2010 10:22
    Dienstag, 7. Dezember 2010 09:32
    Beantworter
  • Hallo Rico,

    der Parameter "Connect Timeout" bestimmt, wann es beim Anmeldevorgang es zum Timeout kommt, wenn z.B. der Server nicht erreichbar ist.

    Es gibt noch beim OleDbCommand das Property CommandTimeout, das Du setzen kannst.

    Warum verwendest Du überhaupt OleDB Klassen, es gibt auch den SqlClient der optimaler für den Zugriff auf den SQL Server ist?


    Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de
    • Als Antwort markiert Rico Fiedler Dienstag, 7. Dezember 2010 10:23
    Dienstag, 7. Dezember 2010 09:37
  • Hallo Elmar
    Wie sieht es aus, wenn im SQL Server der Timeout z.B. auf 30 Sekunden gesetzt ist. Wir da nicht trotzdem nach 30 Sekunden ein Timeout ausgelöst, selbst wenn der CommandTimeout höher oder auf 0 gesetzt wird?
    Wir hatten mal so ein Problem und konnten es dann durch das Optimieren der Query lösen.
    Gruss
    Henry

    Hallo Rico,

    Dafür der OleDbCommand.CommandTimeout Parameter zuständig,
    im Standard wären das 30 Sekunden, setzt Du ihn auf 0 wird endlos gewartet
    (naja, oder bis der Anwender das Programm abbricht ;-)

    Der Connect Timeout Parameter legt nur fest, wie lange auf den Verbindungsaufbau
    gewartet wird, für die Befehlsausführung hat er keine Bedeutung.
    Und auch den RemoteTimeout solltest Du ihn Ruhe lassen, der regelt die Einstellung für Verbindungsserver.

    Wenn es sich bei beiden Datenbank um eine SQL Server DAtenbank handelt,
    wäre der Einsatz des SqlClients von SqlBulkCopy u. U. eine schnellere Variante.
    Das hängt aber vom spezifischen Szenario ab.

    Gru�? Elmar

    Dienstag, 7. Dezember 2010 10:00
  • Hallo,

     

    danke für Eure schnellen Antworten. Manchmal sieht man den Wald vor lauter Bäumen nicht. Natürlich ist es der Parameter CommandTimeout, nich ConnectionTimeout, der angepasst werden muss.

     

    PS: Ob ich OleDB oder SqlClient verwende hat an dieser Stelle meiner Meinung kaum Einfluß, da ich ein Statement in der Form

    Insert into Table1 Select from Table2
    

    verwende, bei dem sich Alles auf dem Server abspielt.Ich werde den SqlClient trotzdem mal auspobieren.

     

    Vielen Dank Rico

    Dienstag, 7. Dezember 2010 10:22
  • Hallo Henry,

    der SQL Server gibt für Client Verbindungen keinerlei Einstellungen vor.
    Die Vorgabe erfolgt durch die Treiber (ODBC, OleDb, SqlClient) selbst,
    die dafür eine CommandTimeout (OleDb, SqlClient) Eigenschaft
    bzw. Methode SQLSetStmtAttr (ODBC) kennen.

    Die oftmals (irrtümlich) angepasste Option remote query timeout kontrolliert
    die Einstellung für Verbindungsserver bzw. verteilte Abfragen. Zitat von dort:
    Der Wert hat keine Auswirkungen auf von Database Engine (Datenbankmodul) empfangene Abfragen.

    Gruß Elmar

    Dienstag, 7. Dezember 2010 10:31
    Beantworter
  • Hallo Elmar
    Danke für Antwort und den Link. Werde mich das nächste Mal ein bisschen intensiver damit beschäftigen.
    Gruss
    Henry

    Hallo Henry,

    der SQL Server gibt für Client Verbindungen keinerlei Einstellungen vor.
    Die Vorgabe erfolgt durch die Treiber (ODBC, OleDb, SqlClient) selbst,
    die dafür eine CommandTimeout (OleDb, SqlClient) Eigenschaft
    bzw. Methode SQLSetStmtAttr (ODBC) kennen.

    Die oftmals (irrtümlich) angepasste Option remote query timeout kontrolliert
    die Einstellung für Verbindungsserver bzw. verteilte Abfragen. Zitat von dort:
    Der Wert hat keine Auswirkungen auf von Database Engine (Datenbankmodul) empfangene Abfragen.

    Gru�? Elmar

    Dienstag, 7. Dezember 2010 11:02
  • Hallo Rico,

    gerade so ein INSERT ... kann man durch Massenkopieren enorm beschleunigen.
    Denn der Unterschied ist dabei wieviel in die Protokolldatei geschrieben wird.
    Die Option existiert auch für OleDb/ODBC - am einfachsten ist sie jedoch in .NET
    über SqlBulkCopy zugänglich.

    Gruß Elmar

    Dienstag, 7. Dezember 2010 11:52
    Beantworter