PostgreSQL和Entity Framework的超时问题

3

当我尝试通过以下代码通过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);
   }
}

在获取几行数据后,我遇到了超时异常,错误如下:

[Npgsql.NpgsqlException] : {"57014: 由于语句超时而取消语句执行"}

Message: 57014: 由于语句超时而取消语句执行

当我将所有数据都获取到一个列表中时,执行相同操作的代码可以正常工作:

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);
   }
}

我怀疑这与PostgreSQL管理其连接池的方式有关,但我不知道如何通过Entity Framework正确地处理它。

1个回答

5
这可能与Npgsql管理超时的方式有关。在当前版本中,Npgsql设置了PostgreSQL的statement_timeout变量,这会导致PostgreSQL在一段时间后生成超时错误。这种方法的问题在于,statement_timeout不可靠,因为它包括网络时间、客户端处理时间等,所以客户端花费太多时间可能会使服务器生成错误。
在您的示例中,调用ToList()意味着您立即下载所有结果,而不是逐步迭代它们。我承认这很奇怪,因为如此短的客户端处理(即Console.WriteLine)可能会引入足以触发后端超时的延迟(命令超时设置为多少?)。
请注意,由于statement_timeout的不可靠性,Npgsql的下一个主要版本将完全删除后端超时 - 请参见https://github.com/npgsql/npgsql/issues/689。目前,您可以通过将Backend Timeouts连接字符串参数设置为false来手动禁用后端超时(请参见http://www.npgsql.org/doc/3.0/connection-string-parameters.html)。

我没有设置命令超时时间,只是使用默认值。 - Amine Kerkeni
1
好的,有可能是Console.WriteLine添加了足够的延迟,以至于触发了这种行为...我建议总体上禁用后端超时。 - Shay Rojansky
1
通过将 Backend Timeouts=false 添加到连接字符串中,它可以完美地工作。 - Amine Kerkeni
1
链接已经失效。正确的链接应该是http://www.npgsql.org/doc/3.1/connection-string-parameters.html,但由于编辑少于6个字符,系统不允许我进行修改。 - Owen Pauling
4
Owen发布的链接现在也失效了... 目前有效的链接是http://www.npgsql.org/doc/connection-string-parameters.html。 - Andrew
1
2021年,您需要添加Command Timeout=0 - Ian Turton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接