简体   繁体   English

执行 DbCommand 失败,因为超时已过期 .net 核心

[英]Failed executing DbCommand because timeout expired .net core

My goal is to provide simple API to retrieve data from Payments (~400 rows) table which consists 5 columns.我的目标是提供简单的 API 来从包含 5 列的Payments (约 400 行)表中检索数据。

Payment: Id (int),
PaymentsNumber (tinyint),
Rate (decimal(18,2)),
ProductType (tinyint),
ClientClubType (tinyint).

Users can make posts request with with the request params of (should return ~12 rows):用户可以使用请求参数(应返回 ~12 行)发出帖子请求:

PaymentsRequest 
{
    public int? PaymentsNumber { get; set; }
    public byte? ProductType { get; set; }
    public byte? ClientClubType { get; set; }
}

Using EF-Core:使用 EF 核心:

services.AddDbContext<MyContext>(cfg => cfg.UseSqlServer(Configuration.GetConnectionString(...),optionsBuilder => optionsBuilder.CommandTimeout(60)));

public async Task<IEnumerable<Payments>> GetPaymentsAsync(PaymentsRequest request)
{
    IQueryable<Payments> query = this._context.Set<Payments>();
    query = query.Where(filter => 
                        (request.ClientClubType == null || filter.ClientClubType == request.ClientClubType) &&
                        (request.ProductType == null || filter.ProductType == request.ProductType) &&
                        (request.PaymentsNumber == null || filter.PaymentsNumber == request.PaymentsNumber));

    return await query.ToListAsync();
}

On azure application insights I can see 2 consecutive logs, caused by the same exception:在 azure 应用程序洞察中,我可以看到 2 个连续的日志,由相同的异常引起:

  1. Log1: Failed executing DbCommand. Log1:执行 DbCommand 失败。
  2. Log2: Execution Timeout Expired. Log2:执行超时已过期。 The timeout period elapsed prior to completion of the operation or the server is not responding.操作完成前超时时间已过或服务器未响应。

The Log1 is (while there is no need to write here the log2): Log1 是(虽然这里不需要写 log2):

Failed executing DbCommand (65,238ms) [Parameters=[@__request_ClientClubType_0='?'执行 DbCommand 失败(65,238 毫秒)[Parameters=[@__request_ClientClubType_0='?' (Size = 1) (DbType = Byte), @__request_ProductType_1='?' (Size = 1) (DbType = Byte), @__request_ProductType_1='?' (Size = 1) (DbType = Byte)], CommandType='Text', CommandTimeout='60'] (Size = 1) (DbType = Byte)], CommandType='Text', CommandTimeout='60']

SELECT [p].[Id], [p].[ClientClubType], [p].[PaymentsNumber], [p].[ProductType], [p].[Rate] FROM [Payments] AS [p] WHERE (([p].[ClientClubType] = @__request_ClientClubType_0) AND @__request_ClientClubType_0 IS NOT NULL) AND (([p].[ProductType] = @__request_ProductType_1) AND @__request_ProductType_1 IS NOT NULL) SELECT [p].[Id], [p].[ClientClubType], [p].[PaymentsNumber], [p].[ProductType], [p].[Rate] FROM [Payments] AS [p] WHERE ( ([p].[ClientClubType] = @__request_ClientClubType_0) AND @__request_ClientClubType_0 不是 NULL) AND (([p].[ProductType] = @__request_ProductType_1) AND @__request_ProductType_1 不是 NULL)

My application is a .net core 3.0 application deployed on azure linux webapp.我的应用程序是部署在 azure linux webapp 上的 .net core 3.0 应用程序。

The issue only occurs from production not every time and I can not reconstruct the issue from MSSMS.该问题仅在生产中出现,并非每次都发生,我无法从 MSSMS 重建该问题。 Any idea?任何的想法?

UPDATE:更新:

After @panagiotis-kanavos commented, I've updated my code to:在@panagiotis-kanavos 发表评论后,我将代码更新为:

services.AddDbContextPool<MyContext>(cfg => cfg.UseSqlServer(Configuration.GetConnectionString(...),optionsBuilder => optionsBuilder.CommandTimeout(60)));

public async Task<IEnumerable<Payments>> GetPaymentsAsync(PaymentsRequest request)
{
    IQueryable<Payments> query = this._context.Payments;
    query = query.Where(filter => 
                        (filter.ClientClubType == request.ClientClubType) &&
                        (filter.ProductType == request.ProductType) &&
                        (filter.PaymentsNumber == request.PaymentsNumber));

    return await query.ToListAsync();
}
  • Your timeout is 60 seconds this could be increased.您的超时时间为 60 秒,这可以增加。 It's usually not a good idea to do this as it will hide other issues.这样做通常不是一个好主意,因为它会隐藏其他问题。
  • If the table has lots of writes, or something has a long running transaction, it can block/contend with your query.如果该表有大量写入,或者某事有长时间运行的事务,则它可能会阻塞/争用您的查询。
  • If you query is part of a larger begin transaction - end transaction sequence of SQL operations, it may be blocked by other open transactions如果您的查询是 SQL 操作的更大的开始事务 - 结束事务序列的一部分,它可能会被其他打开的事务阻塞
  • Same as last one - If multiple calls are made at the same time/nearly the same time to this query it could slow down processing of each query.与上一个相同 - 如果同时/几乎同时对此查询进行多次调用,则可能会减慢每个查询的处理速度。 I've seen this where a web front end populates a screen of 20 lines of data where each line is an different call to the same web-api endpoint for the same type of data.我见过这样的情况,Web 前端填充 20 行数据的屏幕,其中每一行都是对相同类型数据的相同 Web-api 端点的不同调用。 For example, getting the monthly transaction dollar total for each of the last 12 months.例如,获取过去 12 个月中每个月的每月交易美元总额。

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

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