Не сработал тайм-аут Entity Framework

#entity-framework

#entity-framework

Вопрос:

Недавно мы столкнулись с проблемой, из-за которой процесс, выполнение которого обычно занимало секунды, в один день занимал час, а на следующий день — почти 9 часов. Это отдельная проблема, которую я также расследую, но проблема, о которой я хочу поговорить здесь, заключается в том факте, что рассматриваемый запрос был вызван через Entity Framework с таймаутом в 600 секунд, и когда процесс начал выполняться долго, исключение таймаута не сработало.

В каждом экземпляре процесса, выполняющегося долго, он в конечном итоге успешно завершался без ошибок. Мы не переопределяем ничего, связанного с DbContext, поэтому тайм-аут по умолчанию в 30 секунд все равно должен применяться.

Мы проверили, что запрос все еще выполняется, оценив текущие выполнения на экземпляре SQL Server. Моей первой мыслью было, что запрос завершен, но ошибка с ключевыми столбцами Entity в классе entity для этого представления привела к тому, что проверка заняла целую вечность. В этом объекте есть только 1 столбец ключа сущности, и это PK главной таблицы представления. Мы также подтвердили, что набор данных не возвращал повторяющиеся записи. Таким образом, все указывает на тот факт, что запрос выполняется в течение всего процесса и никаких исключений по тайм-ауту не генерируется.

Кто-нибудь когда-нибудь сталкивался с подобным с EF в своей собственной среде?

Мы используем EntityFramework 6.1.3 и SQL Server Standard 2016 SP2 CU4.

ПРИМЕР КОДА:

EntitiesCommandTimeout= 600

 if (ConfigurationManager.AppSettings.AllKeys.Contains("EntitiesCommandTimeout"))
{
    _entitiesCommandTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["EntitiesCommandTimeout"].ToString());
}

...

using (var db = new myContext())
{
    db.Database.CommandTimeout = _entitiesCommandTimeout;
    List<vwMyView> myViewItems = db.myView.Where(v => v.myColumn == myVariable).ToList();                
}
  

ОБНОВЛЕНИЕ 2019-03-19:
Я забыл упомянуть, что когда один из моих разработчиков запустил этот процесс локально через Visual Studio и файл конфигурации был настроен в соответствии с тем, что мы настроили в Prod, исключение тайм-аута было правильно запущено.

Комментарии:

1. Вы уверены, что запрос не запускает огромное количество последующих запросов, вызванных отложенной загрузкой?

2. Я уверен. Объект не имеет связанных сущностей. Это просто представление представления.

3. Странно. Маловероятно, что ADO.Net команда (какой она и является в конце) проигнорирует тайм-аут команды. Как ведет себя сам SQL-запрос при выполнении в SSMS?

4. Ну, это сложно. Когда мы просто берем q. toString(), создайте переменную для параметра, а затем запустите его, запрос вернулся через 3 секунды. Чего мы не сделали, так это не запустили его точно так же, как EF, используя sp_executesql(). Кроме того, восстановление рабочей среды в тестовую среду непосредственно перед первоначальным выполнением процесса привело к завершению этого процесса через 12 секунд, что является ожидаемым промежутком времени. Это наводит меня на мысль, что план запроса по какой-то причине был восстановлен и перепутал оценки строк. Это совершенно другое расследование, которое мы продолжаем.

5. Необходим минимальный проверяемый пример. Обычно EF придерживается настроек тайм-аута, например, из-за блокировки транзакции. Обычными причинами непредвиденных задержек являются блокировки / взаимоблокировки, но создание представления и имитация открытой блокировки путем создания Tx и вставки записи в DB без фиксации или отката, и EF отключает тайм-аут, как и ожидалось. Установлены ли какие-либо тайм-ауты по умолчанию в вашей командной строке? Каков уровень изоляции в вашей производственной базе данных? («Параметры пользователя DBCC»)