Laden...

SQL Abfrage und Timeout

Erstellt von Loewchen0507 vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.502 Views
Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 14 Jahren
SQL Abfrage und Timeout

Hi,

ich habe einen Dienst geschrieben noch mit Visual Studio 2005 und .Net Framework 2.

Dieser läuft schon eine ganze Weile bei mir. Seit neustem bekomme ich allerdings immer wieder eine Fehlermeldung. Dazu mehr:

Es handelt sich um eine Datenmenge einer anderen Datenbank, welche ich bereits in eine View gesammelt habe. Im code hole ich mir diese Werte mit einem SQL Statement in ein Dataset. Das ganze sieht bei mir so aus:


        static protected DataSet DataSetSql(String SQLStr, SqlConnection conn)
        {
            DataSet DS = new DataSet();
            SqlDataAdapter dataAdpaterAccess = new SqlDataAdapter(SQLStr,conn);

            try
            {
                conn.Open();
                dataAdpaterAccess.AcceptChangesDuringFill = true;
                dataAdpaterAccess.Fill(DS);
                conn.Close();
            }
            catch (Exception ex)
            {
                ErrorLogging("Connectionstring ", SQLStr, "DataSetSql");
                ErrorLogging(ex.GetType().ToString(), ex.Message, "DataSetSql");
            }

            finally
            {
                conn.Close();
            }
            return DS;
        }

Genau an dieser Stelle läuft er dann in die Exception rein.

Die Fehlermeldung lautet dann:
Connectionstring
select kundennummer, kundenname, artikelnummer, [Menge LJ], [Wert LJ], [Menge VJ], [Wert VJ], [Menge VJ-2], [Wert VJ-2], [Menge VJ-3], [Wert VJ-3], [Menge VJ-4], [Wert VJ-4], [Menge VJ-5], [Wert VJ-5] from tbl_umsatz
System.Data.SqlClient.SqlExceptionwTimeout ist abgelaufen. Das Zeitlimit wurde vor dem Beenden des Vorgangs überschritten oder der Server reagiert nicht.

Führe ich das Statement im Management Studio aus, so benötigt er 17 Sekunden. Timeout auf dem SQL Server ist eingestellt auf 600 Sekunden. (Hatte auch schon auf 0 für unendlich gesetzt). Mit dem gleichen Code laufen Zig andere Abfragen deren Connectionstring immer gleich ist. Nur die Abfragen unterscheiden sich.

Wenn jemand eine Idee hat, würde ich mich seeeeehr freuen. 😃

LG Loewchen

3.511 Beiträge seit 2005
vor 14 Jahren

Spontan würde mir einfallen, sich den SQL Profiler zu schnappen und zu schauen, wie lange die Ausführungszeit zur Laufzeit des Programms ist.

Ebenfalls könntest du den CommandTimeout höher setzen, bzw. dir erstmal den aktuellen Wert anschauen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 14 Jahren

der aktuelle Ausführungszeit beträgt zwischen 17 und 20 Sekunden. Dann bricht er ab. Der Command Timeout ist ebenfalls auf 600 Sekunden eingestellt.

J
1.114 Beiträge seit 2007
vor 14 Jahren

Wie sieht deine View aus... Wenn du dort ein Select * drin hast, also nicht die Kolonnen aus der Tabelle namentlich angibst, kann es zu Problemen mit solchen Views führen, wenn sich die zugrunde liegende Tabellenstruktur ändert. Dann verrutschen dir Spalten, was natürlich nachher bei der Ausführung zu Problemen führt.

Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 14 Jahren

Hi Jelly,

sehr gute Anregung.
Musste ich grade mal nachgucken. Aber dort habe ich mir doch tatsächlich mal Mühe gegeben und das Statement ausgeschrieben.

Was können denn Grundlegende Gründe für diese Fehlermeldung sein?

Ich kenn nur diese:
Fehler im SQL Statement
Abgebrochene Verbindung zum SQL Server

Loewchen

1.564 Beiträge seit 2007
vor 14 Jahren

Hallo Loewchen0507

Ist "tbl_umsatz" deine View oder eine Tabelle?

Hast du, wie Khalid geschrieben hat, mal den Profiler angeworfen und geschaut was alles ausgeführt wird?

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

F
10.010 Beiträge seit 2004
vor 14 Jahren

Dieser Fehler kommt meist aus folgendem Grund:

Der SqlServer Express braucht für den ersten Verbindungsaufbau zu einer DB
ziemlich lange, da er so implementiert ist, das er erst dann die DB einliesst
und deren Daten, Indizes, Auth usw bereitstellt.
Auch wirft er viel schneller diese Sachen weg, um Speicher und Rechenzeit zu sparen,
er ist ja nicht auf einem dedizierten Server.

Wenn Du mit dem Managementstudio auf den Server zugreifst, wird die DB ja schon
Initialisiert und nur noch die reine SQL Rechenzeit steht an.

Dein Dienst benötigt aber die ganze Zeit.
Stell also bei der Connection und dem Command den Timeout höher.
Auch ein Abstellen des Poolings kann helfen.

Auch solltest Du nach so langer Zeit evtl nochmal darüber nachdenken,
warum du immer noch statische Zugriffsfunktionen und scheinbar auch globale
Connections benutzt, obwohl hier hunderte von male davon abgeraten wurde.

1.564 Beiträge seit 2007
vor 14 Jahren

Hi FZelle

Der SqlServer Express braucht für den ersten Verbindungsaufbau zu einer DB
ziemlich lange, da er so implementiert ist, das er erst dann die DB einliesst
und deren Daten, Indizes, Auth usw bereitstellt.
Auch wirft er viel schneller diese Sachen weg, um Speicher und Rechenzeit zu sparen,
er ist ja nicht auf einem dedizierten Server.

Guter Punkt! Ich kenne mich leider mit den Express Standardeinstellungen nicht so aus, aber...

@Loewchen:
Bitte führe mal folgendes Statement auf deiner Datenbank aus:

SELECT 
   DATABASEPROPERTYEX(DB_NAME(), 'IsAutoClose') AutoClose,
   DATABASEPROPERTYEX(DB_NAME(), 'IsAutoShrink') AutoShrink

Der AutoClose eben zu dem von FZelle angesprochenen Verhalten führen. Bei AutoShrink bin ich mir nicht sicher ob sich der nur auf die Daten-Files oder auch auf die Log-Files bezieht. Kann aber auch dazu führen dass, auf Grund eines Extends, die Datenbank mal nicht reagiert.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 14 Jahren

Hallo,

also ich habe mal ein wenig rumgespielt.
Auch der Profiler gibt mir beim laufen des Dienstes für diese Abfrage an, dass er ca. 20 Sekunden braucht, bis er die Ergebnisse hat.

Die Statements mit Autoclose und autoshrink haben leider auch nichts gebracht.

Ich benutze hier keine globalen conenctionstrings, auch keine statische Zugriffsfunktion.
Was du da siehst ist lediglich eine Funktion in einer Klasse, die ich dazu verwende mir beliebige Daten aus beliebigen Datenbanken zu holen und diese in ein Dataset zu schreiben, um dann damit weiter zu arbeiten. Ich habe es noch nicht geschafft, alle meine Programme auf SQLLinq umzuschreiben und ich will auch keine Grundsatzdiskussion hervorrufen. Es hatte damals seine Gründe warum das so ist wie es ist. Ich will jetzt erstmal die Ursache für das momentane Verhalten finden.

Loewchen

H
81 Beiträge seit 2008
vor 14 Jahren

Ich glaube eher, dass ein solches Konstrukt gemeint war und nicht globale Connection-Strings:


DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(mstrCon))
{
	try
	{
		SqlCommand cmd = new SqlCommand("SELECT * FROM table WHERE id = \'1'\'", con);					
		con.Open();
		dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));
	}
	catch (Exception exc)
	{
				
	}
}

1.564 Beiträge seit 2007
vor 14 Jahren

Ich habe mir deinen Code nochmal angeschaut. Irgendwie sehe ich aber nicht die Stelle an der du das CommandTimeout auf 600 setzt.

Kann es sein, dass du das ConnectionTimeout auf der Connection gesetzt hast? Setzte mal in deinen Code folgende Zeile ein:

dataAdpaterAccess.SelectCommand.CommandTimeout = 600;

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

F
10.010 Beiträge seit 2004
vor 14 Jahren

@HeRaider:
Nein, so sollte es auch nicht gemacht werden.


DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM table WHERE id = @ID",mstrCon);
da.SelectCommand.Parameters.AddWithValue("@ID", "1");// oder ,1); wenn es ein int wäre
da.Fill(dt);

Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 14 Jahren
fehler gelöst und neuer fehler aufgetreten

Hi Leute,

ich hab es hinbekommen.
Ich habe den Timeout für die Anmeldung höher gesetzt. Nun funktioniert es an dieser Stelle.

Dafür funktionierts jetzt an anderer Stelle nicht mehr. Ich bekomme teilweise Timeouts beim löschen. Um eine Tabelle zu löschen benutzte ich

TRUNCATE TABLE tabelle1

Hat bisher, also mit dem SQL Server 2005 auch wunderbar geklappt. Nun sind wir aber umgezogen auf SQL Server 2008. Welche Timeouts würdet Ihr empfehlen hoch zu setzen?

Loewchen