Сконфигурированная стратегия выполнения SqlAzureExecutionStrategy не поддерживает инициированные пользователем транзакции
Я использую последний v6 Entity Framework вместе с шаблоном UnitOfWork. Это было хорошо на сервере в течение последних нескольких лет.
Я хочу перейти на хостинг Azure и использовать SQLAzure, поэтому начал мигрировать приложение. Однако у меня был ряд проблем.
Во-первых, я постоянно получал эту ошибку
Произошла ошибка транспортного уровня при получении результатов с сервера.
После некоторого поиска в Google, кажется, это распространено, и вам нужно реализовать свой собственный SqlAzureExecutionStrategy
- Кажется, все в порядке. Пока я не узнаю, что он не поддерживает инициированные транзакции!
Затем я наткнулся на это сообщение в блоге - в котором излагаются точные проблемы и приводится пример кода того, как решать проблемы (или я так думал).
Я следил за постом (насколько я знаю) точно. У меня есть настройки класса dBconfiguration, и он запускает SetExecutionStrategy при запуске приложения.
public class EfConfig : DbConfiguration
{
public EfConfig()
{
SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
? (IDbExecutionStrategy)new DefaultExecutionStrategy()
: new CustomSqlAzureExecutionStrategy());
}
public static bool SuspendExecutionStrategy
{
get { return (bool?)CallContext.LogicalGetData("SuspendExecutionStrategy") ?? false; }
set { CallContext.LogicalSetData("SuspendExecutionStrategy", value); }
}
}
Затем у меня есть пользовательский класс, упомянутый выше, под названием "CustomSqlAzureExecutionStrategy", который я поместил ниже и переопределил метод ShouldRetryOn.
public class CustomSqlAzureExecutionStrategy : SqlAzureExecutionStrategy
{
protected override bool ShouldRetryOn(Exception exception)
{
var shouldRetry = false;
var sqlException = exception as SqlException;
if (sqlException != null)
{
foreach (SqlError error in sqlException.Errors)
{
if (error.Number == -2)
{
shouldRetry = true;
}
}
}
shouldRetry = shouldRetry || base.ShouldRetryOn(exception);
return shouldRetry;
}
}
Однако, когда я запускаю свое приложение, я все еще получаю ту же ошибку, с которой я начал, но на этот раз просто указываю на пользовательский класс?
Настроенная стратегия выполнения CustomSqlAzureExecutionStrategy не поддерживает инициированные пользователем транзакции.
Я что-то упустил здесь очевидное? Или не понял что-то? Любая помощь будет принята с благодарностью.
Обновить
Как правило... StackOverFlow резиновая утка. Я действительно прочитал это правильно и обнаружил, что мне нужно вручную установить SuspendExecutionStrategy
в моем UnitOfWork (до BeginTransaction и после Commit).
Так что у меня есть это как раз перед .BeginTransaction()
EfConfig.SuspendExecutionStrategy = true;
И это только после .Commit()
EfConfig.SuspendExecutionStrategy = false;
Это позволяет мне запустить приложение сейчас, но я все еще (редко могу добавить) получаю временное сообщение об ошибке?
Произошла ошибка транспортного уровня при получении результатов с сервера.
3 ответа
В дополнение к приостановке стратегии выполнения вам также нужно обернуть повторяемое действие, включая транзакцию, в ручной вызов стратегии выполнения, см. Мой ответ на Как использовать SqlAzureExecutionStrategy и "Nolock"
Убедитесь, что вы завернули все это в попытке / наконец, чтобы убедиться, что вы установили флаг приостановки обратно в false. также посмотрите на эту ссылку для подробного объяснения: msdn.microsoft.com/en-us/data/dn307226
К сожалению, у меня нет реального ответа на вашу проблему. Но я бы предложил добавить некоторые записи в ваш код, особенно в конструктор EfConfig и в метод получения и установки SuspendExecutionStrategy.
Это помогает мне в большинстве случаев понять проблему.