[英]Find Reason for The wait operation timed out
我有以下代码可以从数据库中获取数据。 它托管在 WCF 服务(IIS 服务器)中。
public DataTable GetDocument(int DocumentID)
{
SqlCommand sqlCommand = null;
SqlConnection sqlConnection = null;
SqlDataAdapter sqlDataAdapter = null;
DataTable dataTable = null;
try
{
sqlConnection = new SqlConnection();
sqlConnection.ConnectionString = "Connection_String";
sqlCommand = new SqlCommand();
sqlCommand.CommandText = "dbo.[Get_Document]";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Connection = sqlConnection;
sqlCommand.Parameters.Add(new SqlParameter("@document_id", SqlDbType.BigInt, 8, ParameterDirection.Input, true, 19, 0, "", DataRowVersion.Proposed, DocumentID));
sqlConnection.Open();
sqlDataAdapter = new SqlDataAdapter(sqlCommand);
dataTable = new DataTable("Document");
sqlDataAdapter.Fill(dataTable);
return dataTable;
}
catch (Exception ex)
{
ErrorLog.LogError(ex, "DocumentID = " + DocumentID);
}
finally
{
if (sqlConnection != null)
{
if(sqlConnection.State != ConnectionState.Closed)
sqlConnection.Close();
sqlConnection.Dispose();
sqlConnection = null;
}
if (sqlCommand != null)
{
sqlCommand.Dispose();
sqlCommand = null;
}
if (dataTable != null)
{
dataTable.Dispose();
dataTable = null;
}
if (sqlDataAdapter != null)
{
sqlDataAdapter.Dispose();
sqlDataAdapter = null;
}
}
return null;
}
它工作正常,但有一段时间我们随机收到以下超时异常。
PARAMETER : DocumentID = 987456
EXCEPTION
Error Message: Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Error Source: .Net SqlClient Data Provider
Error Stack Trace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
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.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
at DAL.DocumentController.GetDocument(int DocumentID)
TargetSite : Void OnError(System.Data.SqlClient.SqlException, Boolean, System.Action`1[System.Action])
INNER EXCEPTION
Error Message: The wait operation timed out
BASE EXCEPTION
Error Message: The wait operation timed out
当此时发生超时异常时,我们使用适当的存储过程参数记录异常。 稍后,当我们调查当时的异常日志时,我们使用相同的参数执行相同的操作,但当时系统的行为符合预期(即使使用相同的参数也无法复制异常)。
据我所知,超时异常涉及很多原因。 我们已经设置了足够的超时时间,所以我们不想在我们的应用程序中增加超时时间。
我们只想知道在特定时间范围内发生超时异常的原因(例如,由于任何死锁、连接问题等)并记录该原因,以便稍后我们可以朝正确的方向进行调查。
有没有办法知道超时异常的原因?
谢谢。
我想你是对的。 超时异常可能是由于客户端请求量超过最大服务器负载或资源死锁。 无论是 WCF 还是 SQL server 都有并发请求限制。 这是配置此功能的模板。
<behaviors>
<serviceBehaviors>
<behavior>
<serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="10000" maxConcurrentInstances="100" />
</behavior>
</serviceBehaviors>
实例化模式和并发模式对客户端请求的处理方式有影响。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/sessions-instancing-and-concurrency
https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.servicebehaviorattribute.concurrencymode?view=netframework-4.8
实例化模式和并发模式的结合可能会导致死锁,从而导致超时异常。
最后,数据库连接字符串最好有一个单独的用户名/密码,因为在 IIS 托管 WCF 应用程序的过程中,它将被 IIS 应用程序池标识替换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.