6

Azure で実行されている LINQ-TO-SQL を使用するかなり大きな Web アプリケーションがあり、SQL-Azure からの一時的なエラーが発生しているため、再試行を実装する必要があります。Transient Fault Handling Frameworkと、その使用方法の例を示すいくつかのサイトは知っていますが、LINQ クエリのすべてを次のようなものでラップする必要があるようです。

RetryPolicy retry = new RetryPolicy<MyRetryStrategy>(5, TimeSpan.FromSeconds(5));
Result = retry.ExecuteAction(() =>
{
   … LINQ query here...
});

私のデータ層に何百もの LINQ クエリがあると、これは非常に面倒に見えます。さらに、多くの場合、結果が列挙されるまで実際にはクエリが実行されないという事実もあります。たとえば、データ層のほとんどの関数は、ビジネス層まで IQueryable<> を返します (これにより、リストを返すよりも柔軟になります)。つまり、ビジネス ロジック レイヤーにデータベースの再試行ロジックを散らかさなければならないということです。

したがって、再試行ロジックをデータレイヤーに保持するには、すべてのクエリに .ToList() を配置して、上のレイヤーではなく、すぐに実行されるようにする必要があると思います。

すべてのクエリを変更する必要がなく、一部の基本クラスに再試行ロジックを実装する方法があればいいのにと思います。EFにもこの問題があるようです。

自動再試行を行うように SQL-Azure チームに相談してみるのが本当の答えなので、コードでそれについて心配する必要はありませんか?

4

2 に答える 2

1

このようなものを実装する必要があったので、先に進んでライブラリにしました: https://github.com/daveaglick/LinqToSqlRetry (MIT ライセンスで NuGet で利用可能)。

代わりに次SubmitChanges()のように記述して、呼び出しを再試行できます。SubmitChangesRetry()

using(var context = new MyDbContext())
{
  context.Items.InsertOnSubmit(new Item { Name = "ABC" });
  context.SubmitChangesRetry();
}

Retry()拡張メソッドを使用してクエリを再試行することもできます。

using(var context = new MyDbContext())
{
  int count = context.Items.Where(x => x.Name == "ABC").Retry().Count();
}

特定の再試行ロジックは、ポリシーによって制御できます。内部では、再試行メカニズムは次のようになります。

int retryCount = 0;
while (true)
{
    try
    {
        return func();
    }
    catch (Exception ex)
    {
        TimeSpan? interval = retryPolicy.ShouldRetry(retryCount, ex);
        if (!interval.HasValue)
        {
            throw;
        }
        Thread.Sleep(interval.Value);
    }
    retryCount++;
}

func()呼び出し内の関数とretryPolicyオブジェクトは、用途に基づいて提供されることを理解してください。これにより、再試行ループ中に何が起こっているかがわかります。詳細については、リポジトリを参照してください。

于 2014-12-22T22:49:29.420 に答える
0

LINQ to SQL ではクエリをインターセプトできないため、適切な解決策を知りません。ただし、コードを少しリファクタリングすると役立つ場合があります。(疑似コード) のようなもの:

public Result QueryWithRetry(IQueryable query)
{
      RetryPolicy retry = new RetryPolicy<MyRetryStrategy>(5, TimeSpan.FromSeconds(5)); 
     (() => 
     { 
       return retry.ExecuteAction(query);
     }
}

このメソッドを呼び出すのが少し簡単になりました。

Result = QueryWithRetry(… ここに LINQ クエリ...);

ただし、コードを変更し、すべてのクエリを変更する必要があります。

よろしくお願いします、

明徐。

于 2012-04-18T08:12:02.753 に答える