繁体   English   中英

查找等待操作超时的原因

[英]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.

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