4

現在、データを読み取って更新が必要かどうかを判断し、更新をデータベースにプッシュするメソッドがあります(依存性注入)。この方法は非常に大きな打撃を受け、同時実行に関連するバグ、つまり、最初の更新の前に複数のスレッドがデータを読み取るため、複数の更新が見つかりました。

私はロックを使用してこれを解決しました、それは非常にうまく機能します。代わりにTransactionScopeを使用して同じことを行うにはどうすればよいですか?できますか?ロックのように別のスレッドをブロックしますか?さらに、ロックを使用して行っているように、特定の「ID」を「ロック」することはできますか(IDごとにロックするオブジェクトを格納する辞書を保持しています)?

私はEntityFramework5を使用していますが、リポジトリと作業単位のパターンによって隠されています。

4

1 に答える 1

2

アプリケーション レベルのロックは、この問題の解決にはならない場合があります。まず、通常、単一のレコードまたはレコードの範囲のみをロックする必要があります。次に、後で別の変更をロックして、非常に複雑なコードを作成する必要がある場合があります。

この状況は通常、オプティミスティックまたはペシミスティックな同時実行性で処理されます。

  • オプティミスティック コンカレンシー - データベースで生成された列が追加されます (データベースには通常、タイムスタンプや行バージョンなどの特別な型があります)。データベースは、レコードを更新するたびにその列を自動的に更新します。この列を行バージョンとして構成すると、EF は更新の where 条件に列を含めます => 実行された更新は、指定されたキーと行バージョンでレコードを検索します。レコードが見つかった場合は更新されます。レコードが見つからない場合は、キーを持つレコードが存在しないか、現在のプロセスがデータをロードした後に他の誰かがレコードを更新したことを意味します => 例外が発生し、データを更新して変更を再度保存しようとすることができます。このモードは、あまり更新されていないレコードに役立ちます。あなたの場合、それは別の問題を引き起こす可能性があります。
  • 悲観的同時実行 - このモードでは代わりにデータベース ロックが使用されます。レコードをクエリすると、更新のためにロックされるため、他の誰も更新または直接更新のためにロックすることはできません。残念ながら、このモードは現在 EF で直接サポートされておらず、未加工の SQL を介して実行する必要があります。ペシミスティック コンカレンシーと EF での使用法を説明する記事を書きました。悲観的な同時実行性でさえ、負荷の高いデータベースでは適切なソリューションではない場合があります。

多くの同時プロセスが常に同じデータを更新しようとするソリューションを実際に構築すると、失敗した更新のロックまたは再実行に基づく信頼性の高い高性能ソリューションがないため、再設計が必要になる可能性があります。

于 2013-03-05T19:10:30.970 に答える