Blog

The timeout period elapsed prior to completion of the operation or the server is not responding.

“Command Timeout” is not equal to “Connection Timeout”.
 
A few days ago I had an application that was throwing the following error:
 
“Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding…”
 
It was an obvious error, a database timeout. I reviewed the Connection String and it didn’t have the property “Connection Timeout” (The default connection timeout is 30 seconds). So I added the property and set it to 600 seconds.
 

<connectionStrings>

<add name="ConnectionString" connectionString="Data Source=localhost\SQLEXPRESS;Integrated Security=SSPI;Connection Timeout=600;" />

</connectionStrings>

 
The result was the same: “Timeout expired”. The new timeout wasn’t being applied. I searched in several forums about the error and all said: “Increase the Connection Timeout”.
 
So, I looked at the code and we had the CommandTimeout hardcoded:
 

private void ExecuteCommand(string commandText, string connectionString)

{

using (var connection = new SqlConnection(connectionInfo))

{

       connection.Open();

       var command =

              new SqlCommand(commandText, connection)

            {

              CommandType = CommandType.Text,

                  CommandTimeout = 120

};

      command.ExecuteNonQuery();

}

}

 

It was obvious for me. Remove the hardcoded CommandTimeout .Letting us the following code:
 

private void ExecuteCommand(string commandText, string connectionString)

{

using (var connection = new SqlConnection(connectionInfo))

{

       connection.Open();

       var command =

              new SqlCommand(commandText, connection)

            {

              CommandType = CommandType.Text,

                  CommandTimeout = 120

};

      command.ExecuteNonQuery();

}

}

 

However it didn’t work.

After some research I found on the documentation that the ConnectionTimeout on the connection object it is NOT inherited by the command object (I think should be). So, you have to set the CommandTimeout property of the SQLCommand
The ConnectionTimeout handles the time to wait while trying to establish a connection.
 
The CommandTimeout handles the time to wait before terminating the attempt to execute a command.
 
And we finished with something like this:
 

private void ExecuteCommand(string commandText, string connectionString)

{

using (var connection = new SqlConnection(connectionInfo))

{

       connection.Open();

       var command =

              new SqlCommand(commandText, connection)

            {

              CommandType = CommandType.Text,

                  CommandTimeout = connection.ConnectionTimeout

};

      command.ExecuteNonQuery();

}

}

 

We set SqlCommand.CommandTimeout equal to Connection.ConnectionTimeout. So we will have the same timeout for the Connection and for the Command that executes the instruction.
 
Using this approach you’ll have the conclusion:
• The timeout will be configurable from the web.config (or app.config) file.
• You just will be worried by ONE AND ONLY ONE timeout.
• You’ll save a lot of headaches with the “Timeout errors”

 
 

Comments

On 11 Nov 2009 03:20, Stefan said:

IMHO I think it is a bad idea. Why do you want to wait for (in your case) 600 seconds = 10 loooong minutes before you realize that your server is not even responding...

On 18 Nov 2009 11:14, Osvaldo Orozco Diaz said:

I agree with you. 10 minutes is a looong time before you realize that the SQL server is not responding. However, when we code the method, we were restoring a database backup. So, the 10 minutes was expected to wait for. In this case we could have two connections strings with different timeouts, One for every connection and the other one called “ConnectionStringBackup” with the 600 seconds time out for the backup. The connections string sent to the ExecuteCommand must be handled by the business layer. To decide which connection string should be used. If you don’t want to wait 10 minutes for the connection to the database then you should use another parameter, something like “private void ExecuteCommand(string commandText, string connectionString, int commandTimeout)” You’ll have just one connection string and you’ll have to add two new variables to your “app.config” to handle the connection timeouts. This will result in three variables just for the timeouts (if you want the command timeouts to be customized) and one extra parameter to handle in your business layer. (Remember that ASP.NET handles in an easy way the connection strings) Additionally, if you separate the timeouts, it will be nice to add two more try-catchs; one when you open the connection to the database and one when you execute the command. Something like (this code could not build): private void ExecuteCommand(string commandText, string connectionString, int commandTimeout) { using (var connection = new SqlConnection(connectionInfo)) { try { connection.Open(); } catch(TimeoutException e) { Throw new exception (“The Connection timeout to the database expired.”) } var command = new SqlCommand(commandText, connection) { CommandType = CommandType.Text, CommandTimeout = connection.ConnectionTimeout }; try { command.ExecuteNonQuery(); } catch(TimeoutException e) { Throw new exception (“The Command timeout expired.”) } } } If you don’t implement this code you’ll end with the same problem that I had. A “Connection timeout error” and you won’t know if it is for the connection of for the command. The main idea of this article is to highlight that there are TWO timeouts. The connection timeout and the command timeout, and the command timeout doesn’t inherit the connection timeout. The second approach is to keep it simple, just one timeout. I think that adding a new connection string is easier than adding a new parameter to the method ExecuteCommand and two new configuration keys for the command timeouts. However, with the adding of these parameters you’ll have more control over your class. Thanks for your time for read and answer this post. These comments add value to the post by identifying weakness and suggesting new solutions.

Leave a comment

 
 
 
 
CAPTCHA Image Validation