• FoOnEeN
  • Registratie: Juli 2003
  • Laatst online: 06-02 19:28
Ik heb voor een klant een webservice project ontwikkeld dat voornamelijk een groot aantal queries uitvoert op meerdere databases. Een van deze queries triggerde om de een of andere reden gisteren een Timeout exceptie met de volgende melding:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlDataReader.ConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader() + regel verwijzing naar de executereader methode

Het gekke is dat deze query nooit eerder een timeout heeft getriggered en al maanden zonder problemen werkt. De meest voor de hand liggende oplossing is het verhogen van de timeout omdat de query een te lange uitvoertijd heeft, echter is dat hier niet het geval. Wanneer ik handmatig de query uitvoer in query analyser dan heeft deze een uitvoertijd van 4 seconden terwijl de CommandTimeout van het object op 10 minuten staat. Toch triggert de query deze foutmelding.

Het kan ook niet zo zijn dat de query in sommige gevallen wel een langere uitvoertijd heeft aangezien er gelogd wordt wat de complete uitvoertijd van het stuk code is, en deze haalt net de 50 sec in totaal, bij lange na dus geen 10 minuten.

Ook is het niet zo dat de server niet beschikbaar is gedurende dit tijdstip want in de 50 sec dat deze job nodig heeft om te draaien worden er ergens tussen de 10-50 queries uitgevoerd, welke allemaal goed gaan.

Mijn vraag is dus eigenlijk, is er een andere fout die deze foutmelding kan triggeren en hoe kan je dit oplossen? De CommandTimeout heeft dus geen effect


Code die ik gebruik:

//Create command object
SqlCommand cmdCreateClientOrders = new SqlCommand();
cmdCreateClientOrders.Connection = dbConnection;
cmdCreateClientOrders.CommandType = CommandType.StoredProcedure;
cmdCreateClientOrders.CommandText = "CreateClientOrders";
cmdCreateClientOrders.CommandTimeout = 600; //10 minuten

try
{
//Open connection
dbConnection.Open();

//Create reader
SqlDataReader reader = cmdCreateClientOrders.ExecuteReader();

if (reader != null)
{
//Check if any rows have been returned
if (reader.HasRows)
{
//Loop through the records, an object and add it to the list
while (reader.Read())
{
//Ophalen gegevens, teveel irrelevante code
}
}

//Close objects
reader.Close();
}

//Close the connection
dbConnection.Close();
}
catch (Exception ex)
{
//Log the error
errorLog.LogError("CreateClientOrders", "Error creating the clientorders: " + ex.Message + " " + ex.StackTrace, DateTime.Now);
}
finally
{
//Close the connection if it's still open
if (dbConnection.State == ConnectionState.Open)
{
dbConnection.Close();
}
}

  • FoOnEeN
  • Registratie: Juli 2003
  • Laatst online: 06-02 19:28
Ik heb er vandaag nog eens naar gekeken en naar lang zoeken kwam ik er achter dat het ook mogelijk is dat dit gebeurt wanneer een andere transactie nog niet gecommit is en dezelfde gegevens gebruikt. Hierdoor blijft de tabel of een gedeelte ervan gelockt waardoor alle queries hierop met de betreffende foutmelding falen.

Probleem is echter dat ik niet kan nagaan of er op het moment van het triggeren ook echt een andere transactie de boel gelocked heeft, waardoor dit de waarschijnlijke oorzaak is van het probleem, maar dat ik dat dus ook nooit zeker weet.

Als er overigens mensen zijn die andere mogelijke oorzaken/oplossingen weten dan hoor ik dat graag :).