我们有一个用.Net Core(当前为v2.2)编写的Web应用程序,并且以Angular作为前端。 如果我在后端对一个路由进行ajax调用,这反过来又打开了一个dbcontext来执行查询,那么我们将遇到对其他任何路由的所有后续ajax调用被阻塞,直到查询第一个控制器路由已经完成了。 (不,它不是SQL Server中的DB Lock。它具有不同的表)。
第一条路线中的代码示例(出于示例目的,该过程需要20秒):
public IActionResult GetBusinessesByNaceAndAmount(int take)
{
using (ConsumentContext consumentContext = new ConsumentContext())
{
var data = consumentContext.Businesses.AsNoTracking().Where(b => b.Established_date != null).GroupBy(b => new { Code = b.Business_code.Substring(0, 2) }).Select(b => new
{
BusinessName = b.First().Business_code.Substring(0, 2),
Businesses = b.Where(bl => bl.Established_date != null).OrderBy(bl => bl.Established_date).Select(bl => new { BusinessName = bl.Name, Amount = 10 }).Take(10).ToList(),
}).Take(take).ToList();
return Ok(data );
}
}
然后,我在一毫秒后又在前端执行另一个调用:
public IActionResult GetCustomers()
{
using (ConsumentContext consumentContext = new ConsumentContext())
{
var customers = consumentContext.Customers.AsNoTracking().Take(5).ToList();
return Ok(customers);
}
}
即使第二个端点的查询仅花费几毫秒,它的TTFB仍保持到第一个端点完成。
我不知道它是否与它有任何关系,但是我们的后端当前正在linux环境(Docker容器)中运行,并且正在通过TCP / IP与我们的MSSQL服务器进行通信(是的,它被锁定在防火墙)。
答案 0 :(得分:1)
您的问题似乎是服务器可用线程不足以处理操作,或者在Angular应用程序中您不是同时进行API调用而是按顺序进行。
要释放长时间运行的DB调用中的线程,您可以尝试将第一个操作更改为async
操作,以便不冻结线程,例如
public async Task<IActionResult> GetBusinessesByNaceAndAmount(int take, CancellationToken token)
{
using (ConsumentContext consumentContext = new ConsumentContext())
{
var data = await consumentContext.Businesses
.AsNoTracking()
.Where(b => b.Established_date != null)
.GroupBy(b => new { Code = b.Business_code.Substring(0, 2) })
.Select(b => new
{
BusinessName = b.First().Business_code.Substring(0, 2),
Businesses = b.Where(bl => bl.Established_date != null)
.OrderBy(bl => bl.Established_date)
.Select(bl => new { BusinessName = bl.Name, Amount = 10})
.Take(10).ToList(),
})
.Take(take)
.ToListAsync(token);
return Ok(data);
}
}
如果您的服务器用尽了线程来处理该操作,这可能会有所帮助。
您还可以验证您的Angular代码。如果您的应用程序正在等待第一次API调用的结果,那么上面的代码将无济于事-您应该同时进行所有调用。