简体   繁体   中英

Simple LINQ to Entities update throwing 'Timeout expired'

The simple method below is throwing a timeout error and I can't figure out why this might be. This may be executed in multiple times in succession and I'm wondering if this could be the cause?

public static Boolean UpdateMessageState(int messageId, int stateId, string message)
{
    var repo = new MailItemRepository();
    try
    {
        var objTask = repo.GetMailByMailId(messageId);

        objTask.State = stateId;
        objTask.Result = message;
        repo.Save();

        return true;
    }
    catch (Exception ex)
    {
        logger.Info(ex.Message);
        logger.Info(ex.InnerException);
        return false;
    }
}

Error trace:

2012-07-02 15:26:38.1002|INFO|EF.Methods.MailMethods.UpdateMessageState|System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   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.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)
   at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)

EDIT:

I've removed LINQ from the equation and now have this as UpdateMessageState

public static Boolean UpdateMessageState(int messageId, int stateId, string message)
    {

        var success = true;

        var conn =
            new SqlConnection(
                "Data Source=...");

        try
        {

            //logger.Info(String.Format("S1:messageId={0},stateId={1},message={2}", messageId, stateId, message));

            var cmdPers = new SqlCommand("procMailQueueStatusUpdate", conn)
                              {
                                  CommandType = CommandType.StoredProcedure
                              };

            cmdPers.Parameters.Add("@MessageId", SqlDbType.Int);
            cmdPers.Parameters.Add("@StateId", SqlDbType.Int);
            cmdPers.Parameters.Add("@Message", SqlDbType.VarChar, -1);

            cmdPers.Parameters["@MessageId"].Value = messageId;
            cmdPers.Parameters["@StateId"].Value = stateId;
            cmdPers.Parameters["@Message"].Value = message;

            conn.Open();
            cmdPers.ExecuteNonQuery();

        }
        catch (Exception ex)
        {
            logger.Info(ex.Message);
            success = false;
        }
        finally
        {
            if (conn.State == ConnectionState.Open)
            {
                conn.Close();
                conn.Dispose();
            }
        }
        return success;
    }
}

My guess is that sql sever is just responding a little slower than you are expecting. This can be caused by several things (memory pressure, disk IO, resource waits, network latency, etc).

Just increase the timeout on your connection and you should be golden. You can make this change adding the "Connect Timeout" keyword into your current connection string

http://www.connectionstrings.com/Articles/Show/all-sql-server-connection-string-keywords

ie

Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;Connect Timeout=60

If this fails, try increasing the command timeout. When using ADO you can do it as follows.

using (SqlConnection con = new SqlConnection())
using(SqlCommand cmd = new SqlCommand())
{            
    cmd.CommandTimeout = 60;
    cmd.Connection = con;
}

To set this property in linq to entities use the following method

using (MyEntities db = new MyEntities())
{
  db.CommandTimeout = 60;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM