【发布时间】:2012-07-02 23:46:34
【问题描述】:
下面的简单方法是抛出超时错误,我不知道为什么会这样。这可能会连续执行多次,我想知道这是否是原因?
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;
}
}
错误跟踪:
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)
编辑:
我已经从等式中删除了 LINQ,现在将其作为 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;
}
}
【问题讨论】:
-
不要返回 true 或 false,它已经过时并且现在是糟糕的设计。取而代之的是一个空白。
-
GetMailByMailId是映射函数吗?你能从 SSMS 运行它吗?它运行良好吗?你可以使用 ADO.NET 运行一个普通的查询(例如,调用这个函数),它会运行良好吗? -
您是否尝试过使用 sql 分析器来查看传递给您的数据库的确切 sql?
-
尼克,请记住 SSMS 中的超时时间非常高(实际上默认情况下它是无限的)。虽然 .net 数据连接器中的默认超时时间要低得多(15 秒)。因此,如果存储的 proc 长时间运行,SSMS 根本不会退缩,但代码中的 sql 连接会
-
Nick,回到 @Aducci 的建议,使用 SQL Profiler 跟踪“SQL 语句完成”事件,让它返回 TextData,并将 Duration 列过滤为相当长的时间(10 秒)所以我们可以看到实际导致超时的sql。
标签: c# entity-framework exception-handling linq-to-entities timeout