Недавно я обновил свой проект с EF5 до EF6. В этом проекте у меня есть рабочая роль Azure, которая запускается периодически и запускает хранимую процедуру в SQL Azure, которая обновляет кучу информации в базе данных и занимает в среднем 1,5 часа для выполнения. Когда это будет сделано, рабочая роль выполняет дополнительные задачи с возвращаемым результатом хранимой процедуры.
Раньше это работало безупречно в EF5, но в EF6 каждый раз происходит сбой с одной из следующих ошибок:
Ошибка Произошла ошибка транспортного уровня при получении результатов с сервера. (поставщик: Session Provider, ошибка: 19 — Физическое соединение не используется)
Ошибка. Сеанс был прерван, так как он получил слишком много блокировок. Попробуйте прочитать или изменить меньше строк за одну транзакцию. В текущей команде произошла серьезная ошибка. Результаты, если таковые имеются, должны быть отброшены.
Я пробовал следующие вещи, чтобы исправить ошибку:
- Проверено, что все чтения хранимых процедур имеют модификатор
WITH (NOLOCK)
- Увеличен тайм-аут контекста Entity Framework до 5 часов.
- Удален новый
SqlAzureExecutionStrategy
, который был поставлен на место, и возвращен для использованияDefaultExecutionStrategy
. - Удалены все транзакции, которые происходили в хранимой процедуре.
- Убедитесь, что этот шаг в рабочей роли выполняется в собственном контексте.
Пример кода:
using (var dbContext = new EFEntityContext())
{
// set the timeout to 5 hours
var objectContext = (dbContext as IObjectContextAdapter).ObjectContext;
objectContext.CommandTimeout = 18000; // 5 hours
// update all active curriculums
var result = dbContext.usp_MyLongRunningProd();
// log the results of the operation
Trace.TraceInformation(result);
}
Кроме того, хранимые процедуры считывают большую таблицу в курсор, перебирают ее и выполняют анализ и изменение данных на основе каждого элемента. Мне не нужно, чтобы курсор находился в какой-либо транзакции, и я не использую тот, о котором я знаю, если только EF не делает его, и это проблема.