简体   繁体   English

PostgreSQL和实体框架的超时问题

[英]Timeout issue with PostgreSQL and Entity Framework

When I try to query a PostgreSQL database through EntityFramework6.Npgsql with the following code: 当我尝试使用以下代码通过EntityFramework6.Npgsql查询PostgreSQL数据库时:

using (MyDbContext context = new MyDbContext())
{
   var res = (from b in context.mytable select new { b.Name, b.Age }); 
   foreach (var row in res)
   {
      Console.WriteLine(row.Name + " - " + row.Age);
   }
}

I get a timeout exception after fetching few lines with the following error: 在获取几行后出现以下错误,我收到超时异常:

[Npgsql.NpgsqlException] : {"57014: canceling statement due to statement timeout"} [Npgsql.NpgsqlException]:{“57014:由于语句超时而取消语句”}

Message: 57014: canceling statement due to statement timeout 消息:57014:由于语句超时而取消语句

When I execute the same operation while fetching all the data to a List, the code works fine: 当我在将所有数据提取到List时执行相同的操作时,代码工作正常:

using (MyDbContext context = new MyDbContext())
{
   var res = (from b in context.mytable select new { b.Name, b.Age }).ToList(); 
   foreach (var row in res)
   {
      Console.WriteLine(row.Name + " - " + row.Age);
   }
}

I suspect that it is related to the way PostgreSQL manages its connection pool but I don't know how I could handle it correctly through Entity Framework. 我怀疑它与PostgreSQL管理其连接池的方式有关,但我不知道如何通过Entity Framework正确处理它。

This is probably related to the way Npgsql manages timeouts. 这可能与Npgsql管理超时的方式有关。 In current versions, Npgsql sets the PostgreSQL statement_timeout variable which causes PostgreSQL to generate a timeout error after some time. 在当前版本中,Npgsql设置PostgreSQL statement_timeout变量,导致PostgreSQL在一段时间后生成超时错误。 The problem with this method is that statement_timeout is unreliable for this: it includes network time, client processing time, etc. so too much time spent on the client could make the server generate the error. 这种方法的问题在于, statement_timeout对此不可靠:它包括网络时间,客户端处理时间等。因此在客户端上花费的时间太多会使服务器生成错误。

In your example, calling ToList() means that you immediately download all results, rather than iterate over them little by little. 在您的示例中,调用ToList()意味着您立即下载所有结果,而不是一点一点地迭代它们。 I do admit it's strange that such short client processing (ie Console.WriteLine ) could introduce a delay sufficient to trigger a backend timeout (what is the command timeout set to?). 我承认奇怪的是,这样的短客户端处理(即Console.WriteLine )可能会引入足以触发后端超时的延迟(命令超时设置为什么?)。

Note that the next major version of Npgsql will remove backend timeouts entirely because of the unreliable nature of statement_timeout - see https://github.com/npgsql/npgsql/issues/689 . 请注意,由于statement_timeout的不可靠特性,Npgsql的下一个主要版本将完全删除后端超时 - 请参阅https://github.com/npgsql/npgsql/issues/689 For now you can manually disable backend timeouts by setting the Backend Timeouts connection string parameter to false (see http://www.npgsql.org/doc/3.0/connection-string-parameters.html ). 现在,您可以通过将Backend Timeouts连接字符串参数设置为false来手动禁用后端超时(请参阅http://www.npgsql.org/doc/3.0/connection-string-parameters.html )。

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

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