web-dev-qa-db-ja.com

構成された実行戦略「SqlAzureExecutionStrategy」は、ユーザーが開始したトランザクションをサポートしていません

UnitOfWorkパターンとともにEntityFrameworkの最新のv6を使用しています。これは、過去数年間、サーバーでは問題ありませんでした。

Azureホスティングに移行してSQLAzureを使用したいので、アプリの移行を開始しました。しかし、私はいくつかの問題を抱えています。

まず、このエラーが断続的に発生し続けました

サーバーから結果を受信するときに、トランスポートレベルのエラーが発生しました。

グーグルを行った後、これは一般的であり、独自の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ラバーダッキング。実際に正しく読んだところ、UnitOfWorkでSuspendExecutionStrategyを手動で設定する必要があることがわかりました(BeginTransactionの前とCommitの後)。

だから私は.BeginTransaction()の直前にこれを持っています

_EfConfig.SuspendExecutionStrategy = true;
_

そしてこれは.Commit()の直後

_EfConfig.SuspendExecutionStrategy = false;
_

これにより、今すぐアプリケーションを実行できますが、それでも(めったに追加しないかもしれませんが)一時的なエラーメッセージが表示されますか?

サーバーから結果を受信するときに、トランスポートレベルのエラーが発生しました。

14
leen3o

一時停止フラグをfalseに戻すために、すべてをtry/finallyでラップするようにしてください。詳細な説明については、このリンクも参照してください: ヘルプリンク

2
Donuts

実行戦略を一時停止することに加えて、実行戦略への手動呼び出しにトランザクションを含めて、再試行するアクションをラップする必要もあります。 SqlAzureExecutionStrategyと "Nolock"の使用方法 に対する私の答えを参照してください。

2
Andriy Svyryd