Сконфигурированная стратегия выполнения 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.

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

Другие вопросы по тегам