2016-04-20 2 views
3

Когда я пытаюсь сделать запрос к базе данных PostgreSQL через EntityFramework6.Npgsql со следующим кодом:Тайм-аут проблемы с PostgreSQL и Entity Framework

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: canceling statement due to statement timeout"}

Message: 57014: canceling statement due to statement timeout

Когда я выполняю ту же операцию при извлечении всех данных в списке, код работает отлично:

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.

ответ

4

Возможно, это связано с тем, как Npgsql управляет таймаутами. В текущих версиях Npgsql задает переменную PostgreSQL statement_timeout, которая заставляет PostgreSQL генерировать ошибку таймаута через некоторое время. Проблема с этим методом заключается в том, что statement_timeout ненадежен для этого: он включает время сети, время обработки клиента и т. Д., Поэтому слишком много времени, затраченного на клиента, может заставить сервер генерировать ошибку.

В вашем примере вызов ToList() означает, что вы сразу же загружаете все результаты, а не перебираете их понемногу. Я признаю, что странно, что такая короткая обработка клиента (то есть Console.WriteLine) может привести к задержке, достаточной для запуска тайм-аута бэкэнд (каков тайм-аут команды, установленный на?).

Обратите внимание, что следующая основная версия Npgsql будет удалять исчерпывающие тайм-ауты полностью из-за ненадежного характера statement_timeout - см. https://github.com/npgsql/npgsql/issues/689. Пока вы можете вручную отключить тайм-ауты backend, установив параметр строки подключения в значение false (см. http://www.npgsql.org/doc/3.0/connection-string-parameters.html).

+0

Я не устанавливаю тайм-аут команды, просто используя значения по умолчанию –

+1

Хорошо, возможно, что 'Console.WriteLine' добавляет достаточную задержку, чтобы вызвать это поведение ... Я бы рекомендовал отключить тайм-ауты Генеральная. –

+1

Добавляя Backend Timeouts = false в строку подключения, он отлично работает. –