TimeOut während SqlDataReader aktiv

02/02/2010 - 19:53 von Martin Schiessling | Report spam
Hallo!

Ich hoffe, dass ich in der richtigen Newsgroup bin, da es sich um ein
Problem mit Zusammenspiel VB.NET und VB6 handelt.

Es làuft folgendes Szenarium:

An einem Windows Server 2003 SBS mit SQL Server 2005 Workgroup Edition làuft
ein Windows Dienst. Dieser Dienst wurde in VB.NET erstellt. Alle 3-4 Stunden
führt dieser Dienst einen SELECT auf eine Tabelle mit einigen JOINS und ca.
30 Spalten aus. In der Haupttabelle sind ca. 40.000 Datensàtze. Durch die
WHERE Einschrànkung sind es ca. 4000 Datensàtze welche wirklich in den Reader
kommen. Es sind einige Indexe auf den Tabellen im Einsatz, trotzdem ist die
Abfrage aufgrund der vielen JOINS eher langsam (vor allem beim ersten
Zugriff, wegen dem Ausführungsplan)


Anbei der Code für die Erstellung der Abfrage:

strConnectionString = "Data Source=" & strServer & ";Initial Catalog=" &
strDatenbank & ";Integrated Security=False;Persist Security Info=False;" &
"User ID=user1;Password=" & strPassword

moConn = New SqlConnection
moConn.ConnectionString = strConnectionString
moConn.Open()

moCommand = New SqlCommand(pstrSQL, moConn)
moCommand.CommandTimeout = 120

oReader = moCommand.ExecuteReader



Mit dem erstellten Reader werden nun die Zeilen sequentiell mit .Read
durchlaufen um unter anderem eine XML Datei zu erstellen und diese über eine
SOAP Nachricht weiter zu senden. Der ganze Vorgang für alle Datensàtze dauert
ca. 4-5 Minuten.


Nun zum Problem:
Gleichzeitig làuft eine Anwendung welche auf die gleiche Datenbank und auf
die gleichen Tabellen zugreift. Diese Anwendung ist in VB6 geschrieben und
verwendet für den Zugriff den SQLOLEDB Treiber.


Anbei der Code für die Erstellung der Abfragen im VB6:

Set conADODB = New ADODB.Connection
conADODB.Provider = "SQLOLEDB.1"
conADODB.Properties("Data Source") = strServer
conADODB.Properties("Initial Catalog") = strDatenbanknamen
conADODB.Properties("User ID") = "user2"
conADODB.Properties("Password") = strPassword
conADODB.CursorLocation = adUseClient
conADODB.ConnectionTimeout = 60
conADODB.CommandTimeout = 120
conADODB.Open

Set rsRecordset = conADODB.Execute(pstrSQL)
oder ohne Recordset:
Call conADODB.Execute(pstrSQL, , adExecuteNoRecords)



Es kommen nun temporàr Fehlermeldungen beim Zugriff auf die Daten im VB6 mit
SQLOLEDB.

Die Fehlermeldung im Detail:
Timeout abgelaufen - Nummer -2147217871
SQL z.B. = "UPDATE " & strTabelle & " SET storno = 1 WHERE ID = 23489;"

Der Fehler im VB6 tritt immer nur dann sporadisch auf, wenn gerade der .NET
Dienst aktiv ist, und der DataReader im Dienst durchlaufen wird. Die Tabelle
welche im VB6 mit dem UPDATE aktualisiert wird, wird auch im DataReader mit
selektiert. Aber der DataReader sollte doch keinen Lock auf die Daten setzen,
oder?

Fragen:
1.) Kann es möglich sein, dass durch die Abfrage im VB.NET Programm ein Teil
der Daten gelockt wird, obwohl "nur" ein DataReader verwendet wird.
2.) Möglicherweise muss die Abfrage im VB.NET geàndert werden?
3.) Macht es Sinn in diesem Fall mit einem WITH NOLOCK Option zu arbeiten
(im VB.NET Dienst)? Ich hab dabei aber ein schlechtes Gefühl bezüglich der
Bad reads, da im VB6 Programm auch Transaktionen verwendet werden.
4.) Sollte im Dienst ein anderer Daten Adapter verwendet werden? Die
Performance ist dabei nicht so wichtig, da dieser Dienst im Hintergrund ruhig
etwas laufen kann.


Zur weiteren Info über die Umgebung:
* die Connection im VB.NET Dienst wird immer korrekt geschlossen und mit
Dispose entfernt
* die Windows Server Maschinen der jeweiligen Systeme sind mit min. 6GB RAM
und Quad Core Prozessoren performant. es gibt auch sonst keinerlei
Performance Probleme mit einem der Anwendungen
* es passiert bei mehreren System das gleiche Problem. Diese Systeme sind
mehr oder weniger ident vom Aufbau (SBS 2003, SQL 2005)
* der Dienst und das VB6 Programm greifen auf den gleichen SQL Server zu
* es gibt auch sonst keine Probleme, es funktioniert sowohl der Dienst mit
dem SOAP als auch die VB6 Anwendung fehlerfrei (außer dem erwàhnten TimeOut
Problem)
* im VB6 Programm arbeiten ca. 10 User an der Datenbank und es passieren
aber nur sehr sporadisch diese TimeOut Fehler (ca. 10 Fehler pro Woche).

Vielen Dank im Voraus für Hilfe und Anregungen,
Martin
 

Lesen sie die antworten

#1 Peter Fleischer
02/02/2010 - 20:30 | Warnen spam
"Martin Schiessling" <Martin schrieb
im Newsbeitrag news:

Es làuft folgendes Szenarium:
...



Hi Martin,
ich würde bei den zur Verfügung stehenden Ressourcen mich vom DataReader
trennen und an dessen Stelle die Daten schnell in einen Puffer einlesen, um
dann aus diesem Puffer die XML-Datei zu erzeugen. Als Puffer eignet z.B. in
eine DataTable, die mit einem DataAdapter gefüllt wird. Zusàtzlich würde ich
die das CommandTimeout im VB6-Programm auf 300 Sekunden hochsetzen.


Viele Gruesse

Peter

Ähnliche fragen