简体   繁体   English

SQL 超时已过。 操作完成前超时时间已过或服务器未响应

[英]SQL Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding

I am using Microsoft.EntityFrameworkCore.SqlServer 2.2.6.我正在使用Microsoft.EntityFrameworkCore.SqlServer 2.2.6。 I have a stored procedure which typically takes 1 to 2 seconds to execute.我有一个存储过程,通常需要 1 到 2 秒才能执行。

I am using .NET Core 2.2 with EF Core to execute that stored procedure.我正在使用 .NET Core 2.2 和 EF Core 来执行该存储过程。

appsettings.json : appsettings.json

{  
    "SqlCommandTimeout": 120, // seconds
    "ConnectionStrings": {
        "DefaultConnection": "Server=serverip;Database=MyDataBase;Integrated Security=True;"
    }
}

In startup.cs I am setting connection string and timeoutstartup.cs我正在设置连接字符串和超时

var sqlCommandTimeout = configuration.GetValue<int>("SqlCommandTimeout");
services.AddDbContext<MyDBContext>(options =>
        {
            options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
                sqlServerOptions => sqlServerOptions.CommandTimeout(sqlCommandTimeout));
        });

This code executes the stored procedure and populates a DTO:此代码执行存储过程并填充 DTO:

public static async Task<IEnumerable<AvailableWorkDTO>> prcGetAvailableWork(this MyDBContext dbContext, int userID)
{            
    var timeout = dbContext.Database.GetCommandTimeout() ?? 120;

    var result = new List<AvailableWorkDTO>();

    using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
    {
        var p1 = new SqlParameter("@UserID", SqlDbType.Int)
            {
                Value = userID
            };

        cmd.CommandText = "dbo.prcGetAvailableWork";
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add(p1);
        cmd.CommandTimeout = timeout;

        await dbContext.Database.OpenConnectionAsync().ConfigureAwait(false);

        using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
        {
            while (await reader.ReadAsync().ConfigureAwait(false))
            {
                var item = new AvailableWorkDTO();
                item.ID = reader.GetInt32(0);
                item.Name = reader.GetString(1);
                item.Title = reader.GetString(2);
                item.Count = reader.GetInt32(3);

                result.Add(item);
            }
        }
    }

    return result;
}

The stored procedure only reads data from couple of tables using READUNCOMMITTED isolation level.存储过程仅使用READUNCOMMITTED隔离级别从几个表中读取数据。 However there is also a another background process that inserts new records into these tables every 3 minutes.然而,还有另一个后台进程每 3 分钟将新记录插入这些表中。

ISSUE问题

Every now and then when number of users increase we are seeing the timeout exception.时不时地,当用户数量增加时,我们会看到超时异常。

System.Data.SqlClient.SqlException (0x80131904): Timeout expired. System.Data.SqlClient.SqlException (0x80131904): 超时已过。

The timeout period elapsed prior to completion of the operation or the server is not responding.在操作完成之前超时期限已过,或者服务器没有响应。

System.ComponentModel.Win32Exception (258): The wait operation timed out System.ComponentModel.Win32Exception (258): 等待操作超时
at System.Data.SqlClient.SqlCommand.<>c.b__122_0(Task 1 result) at System.Threading.Tasks.ContinuationResultTaskFromResultTask 2.InnerInvoke()在 System.Data.SqlClient.SqlCommand.<>c.b__122_0(任务1 result) at System.Threading.Tasks.ContinuationResultTaskFromResultTask 2.InnerInvoke()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,Object 状态)

--- End of stack trace from previous location where exception was thrown --- --- 从抛出异常的先前位置开始的堆栈跟踪结束 ---

at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)在 System.Threading.Tasks.Task.ExecuteWithThreadLocal(任务和 currentTaskSlot)

--- End of stack trace from previous location where exception was thrown --- --- 从抛出异常的先前位置开始的堆栈跟踪结束 ---

at Data.Entities.StoredProcedures.StoredPrcedureExtensions.prcGetAvailableWork(MyDbContext dbContext, Int32 userID) in D:\Jenkins\xx-production\workspace\Src\Common\Data\Entities\StoredProcedures\StoredPrcedureExtensions.cs:line 56在 D:\Jenkins\xx-production\workspace\Src\Common\Data\Entities\StoredProcedures\StoredPrcedureExtensions.cs 中的 Data.Entities.StoredProcedures.StoredPrcedureExtensions.prcGetAvailableWork(MyDbContext dbContext,Int32 用户 ID):第 56 行
at....在....
.... ....
Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,Object controller,对象 [] 参数)

at System.Threading.Tasks.ValueTask`1.get_Result()在 System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext 上下文)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next,Scope& scope,Object& state,Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next,Scope& scope,Object& state,Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)在 Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)在 Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)在 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 上下文)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)在 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext 上下文)
ClientConnectionId:c10da510-509f-4bfb-8b37-58c0ee8fa3b1 ClientConnectionId:c10da510-509f-4bfb-8b37-58c0ee8fa3b1
Error Number:-2,State:0,Class:11at错误号:-2,State:0,Class:11at

Questions问题

  1. I am using EF Core 2.2.我正在使用 EF Core 2.2。 Based on documentation , for certain async methods SqlCommand.CommandTimeout property is ignored.根据文档,对于某些异步方法, SqlCommand.CommandTimeout属性被忽略。 In the above code will the timeout ignored?在上面的代码中,超时会被忽略吗?

  2. SQL Server Profiler shows stored procedure actually gets executed only once by await cmd.ExecuteReaderAsync() line. SQL Server Profiler 显示存储过程实际上仅通过await cmd.ExecuteReaderAsync()行执行一次。 However we still need to keep connection open while reading from the reader.然而,我们仍然需要在阅读阅读器时保持连接打开。 Is the CommandTimeOut includes time takes for reading from the reader? CommandTimeOut是否包括从阅读器读取所需的时间?

  3. At most 100 users may concurrently access this stored procedure.最多 100 个用户可以并发访问此存储过程。 We have double check indexes and also execute scheduled indexing job every day.我们会仔细检查索引,并且每天都会执行预定的索引工作。 We are using我们正在使用

     Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) - 14.0.3048.4 (X64) Standard Edition (64-bit)

    on Windows Server 2019. Which should be able to handle the load.在 Windows Server 2019 上。它应该能够处理负载。 Is there any settings that we need to look?有没有我们需要查看的设置? (SQL Server also has multiple other databases as well) (SQL Server 也有多个其他数据库)

In the above code will the timeout ignored?在上面的代码中超时会被忽略吗?

No.不。

System.Data.SqlClient.SqlException (0x80131904): Timeout expired.

This is a client-side timeout caused by the CommandTimeout.这是由 CommandTimeout 引起的客户端超时。

Is the CommandTimeOut includes time takes for reading from the reader? CommandTimeOut 是否包括从阅读器读取所需的时间?

Yes.是的。 Per docs , SqlCommand.CommandTimeout includes SqlDataReader.Read() time.根据文档, SqlCommand.CommandTimeout 包括 SqlDataReader.Read() 时间。

Is there any settings that we need to look?有什么我们需要看的设置吗?

Turn on the Query Store and track the session wait stats to see if you're seeing blocking, CPU contention or something else.打开查询存储并跟踪会话等待统计信息,以查看您是否看到阻塞、CPU 争用或其他情况。

I also had the same issue, in my case I written the stored procedure code in the following way我也有同样的问题,在我的例子中,我用以下方式编写了存储过程代码

BEGIN TRAN
BEGIN TRY
  some code here....
 --COMMIT TRAN // it is missed or written in the wrong place
END TRY

"COMMIT TRAN" code missed in the stored procedure code but "BEGIN TRAN" is there , due to that previous calls are in waiting state and for the next transaction server will not respond存储过程代码中缺少“COMMIT TRAN”代码,但存在“BEGIN TRAN” ,因为之前的调用正在等待 state 并且下一个事务服务器不会响应

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 EntityFramework核心超时已过期。 操作完成之前经过的超时时间或服务器未响应 - EntityFramework Core Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding 超时已过。 操作完成前超时时间已过或服务器未响应 - Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding EF 代码优先 - 超时已过。 完成前超时时间已过 - EF Code First - Timeout expired. The timeout period elapsed prior to completion 更新数据库将索引添加到表中,并且EF代码优先-超时已过期。 完成之前经过的超时时间 - Update-Database Adding Index To Table And EF Code First - Timeout expired. The timeout period elapsed prior to completion EF、SQL Server - 连接超时已过期。 登录后阶段已过的超时时间 - EF, SQL Server - Connection Timeout Expired. The timeout period elapsed during the post-login phase 超时已过。 在从池中获取连接之前超时时间已过。 - Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. 连接超时已过期。 登录后阶段已过的超时时间 - Connection Timeout Expired. The timeout period elapsed during the post-login phase “信号量超时期限已过期”SQL Azure - “The semaphore timeout period has expired” SQL Azure SQL Azure - 登录后阶段超时 - SQL Azure - The timeout period elapsed during the post-login phase SQL Server Express 2008,联接和超时过期错误消息 - SQL Server Express 2008, Joins, and Timeout Expired Error Message
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM