Сконфигурированная стратегия выполнения "SqlAzureExecutionStrategy" не поддерживает инициированные пользователем транзакции

Я использую последнюю версию 6 Entity Framework вместе с шаблоном UnitOfWork. Это было хорошо на сервере в течение последних нескольких лет.

Я хочу перейти на azure хостинг и использовать SQLAzure, поэтому начал мигрировать приложение. Однако у меня было несколько проблем.

Во-первых, я периодически прерывал эту ошибку

Возникла ошибка транспортного уровня при получении результатов сервер.

После некоторого Googling кажется, что это обычное дело, и вам нужно реализовать свой собственный 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' не поддерживает инициированные пользователем транзакции.

Я пропустил что-то очевидное здесь? Или что-то не понял? Любая помощь будет принята с благодарностью.

Update


Обычно... StackOverFlow резиновая утка. Я действительно прочитал его правильно и обнаружил, что мне нужно вручную установить SuspendExecutionStrategy в моем модуле UnitOfWork (Before BeginTransaction и после Commit).

Итак, у меня это как раз перед .BeginTransaction()

EfConfig.SuspendExecutionStrategy = true;

И это сразу после .Commit()

EfConfig.SuspendExecutionStrategy = false;

Это позволяет мне запускать приложение сейчас, но я все же (редко могу добавить) получить сообщение об ошибке переходного процесса?

Возникла ошибка транспортного уровня при получении результатов сервер.

Ответ 1

В дополнение к приостановке стратегии исполнения вам также необходимо обернуть действие, которое вы повторите, включая транзакцию в ручном вызове стратегии выполнения, см. мой ответ на Как использовать SqlAzureExecutionStrategy и "Nolock"

Ответ 2

убедитесь, что вы завернули все это в try/finally, чтобы убедиться, что флаг suspend установлен на false. также ознакомьтесь с этой ссылкой для получения подробного объяснения: msdn.microsoft.com/en-us/data/dn307226

Ответ 3

К сожалению, у меня нет реального ответа на вашу проблему. Но я бы предложил добавить некоторые записи в ваш код, особенно для конструктора EfConfig и для getter и setter SuspendExecutionStrategy.

Это помогает мне в большинстве случаев понять проблему.