2

シナリオ:

複数のアカウントを持っています。すべてのアカウントには残りのクレジットがあります。すべてのアカウントは複数のユーザーに対応しています。

RemainingCreditフィールドに残りのクレジットを正しく反映させたい(EFを使用してdbを抽象化しています)。

EG初期クレジットがXで、2人のユーザーがログインし、1人がAを使用し、もう1人がBを使用するシナリオでは、最終合計をXABにします(読み取り/変更/保存の順序は関係ありません)。

読んだ後、楽観的同時実行処理は私が探しているものだと思います。それはうまくスケーリングし、これは私のシナリオにとって非常に重要だからです。終了手順は次のようになります。

ComputeRemainingCredit(Double amountToBeDeducted) {
    Account acc = context.Accounts.Where(condition)
    ComputeRemainingCreditInternal(acc, amountToBeDeducted);
}

ComputeRemainingCreditInternal(Account acc, Double amountToBeDeducted) {
try {
    acc.RemainingCredit = acc.RemainingCredit - amountToBeDeducted;
    context.SaveChanges();
}
catch (OptimisticConcurrencyException  ex) {
    context.Refresh(RefreshMode.StoreWinds, acc);
    //now I need to rerun the operation
    ComputeRemainingCreditInternal(acc, amountToBeDeducted);
}
}
  1. これはEFでの楽観的並行性の正しい解釈/実装ですか?
  2. 私の最終的な目的は、RemainingCreditフィールドを最新の状態にすることです。OptimisticConcurrencyExceptionよりも優れたソリューションはありますか?
4

2 に答える 2

2

タイムスタンプまたはバージョン番号として機能するテーブル内のフィールドが必要であり、それをオプティミスティック コンカレンシー チェックに使用します。

フィールドがあるとしVersionます。そのフィールドのConcurrencyModeプロパティをFixedに設定すると、EF がオプティミスティック コンカレンシー チェックを行い、OptimisticConcurrencyException必要に応じて をスローします。

別の方法は、この作業を自分で行うことです。現在のレコードをフェッチし、更新中のレコードのフィールド値と照合してフィールド値を検証し、それに応じて更新を許可または禁止します。

編集http://blogs.msdn.com/b/alexj/archive/2009/05/20/tip-19-how-to-use-optimistic-concurrency-in-the-entity-framework.aspxも参照してください

編集疑似コードで多かれ少なかれ:

bool mustRetry = true;
while (mustRetry)
{
    try
    {
        SpendTheMoney(context, parameters);
        mustRetry = false;
    } catch (OptimisticConcurrencyException exc)
    {
        // Do logging if you need, then just swallow the exception
    }
}
于 2012-12-10T13:50:14.837 に答える
0

別の方法として、データが変更されたために操作が失敗したことを示すエラー メッセージをユーザーに表示し、データの現在の状態を表示することもできます。ユーザーは、それが意図されている場合、操作を再試行することを決定します。

Entity Framework の同時実行性に関する優れた記事は、次の場所にあります。

ASP.NET MVC アプリケーションでの Entity Framework による同時実行の処理

于 2012-12-10T14:11:57.237 に答える