データの同時実行の管理
WCF RIA サービスはデータの一貫性を保証するためにオプティミスティック同時実行制御をサポートしており、データ ソースの更新時に発生する可能性がある競合を処理するロジックを開発者が提供することを前提としています。ユーザーによるデータの更新または削除を許可する場合、別のプロセスによってデータ ソース内のデータが変更されていないことを確認したうえで、データ レコードでその値を無条件に更新したり、レコードから削除したりする必要があります。値が変更されたかどうかを確認しないと、別のプロセスによって設定された値を誤って上書きして、データが矛盾した状態のままになる可能性があります。オプティミスティック同時実行制御では、このような競合はまれであると想定されていますが、データ ソースから取得した値と現在ソースにある値が比較され、値が変更または削除されることがあります。値が一致しない場合は OptimisticConcurrencyException がスローされるので、これに対処する必要があります。
一貫性を保証するための値のチェックを指定する手順については、「方法: オプティミスティック同時実行チェックを有効にする」を参照してください。一貫性を保証するために明示的なトランザクションを使用する方法については、「方法: ドメイン サービスに明示的なトランザクションを追加する」を参照してください。
同時実行制御の属性の使用
既定では、RIA サービス が元のエンティティ全体を変更された値と共にデータ アクセス層に渡して、データの同時実行を確認することはありません。RIA サービス は、RoundtripOriginalAttribute 属性、ConcurrencyCheckAttribute 属性、または TimestampAttribute 属性でマークされたメンバーのみを格納し、渡します。
これらの各属性は、Entity Framework の操作時に、メタデータ クラスのプロパティ、またはメタデータ クラス自体に適用できます。POCO 定義のデータ モデルを操作するときは、CLR 型のプロパティまたはクラスに直接適用することもできます。詳細については、「方法: メタデータ クラスを追加する」を参照してください。これらの属性を適用した後にビルドすると、プロパティまたはクラスに対してクライアントが生成したコードに各属性が表示されます。クラス内のプロパティではなくクラスに対して属性を適用することは、クラスのすべてのメンバーに属性を適用するのと同じです。ConcurrencyCheckAttribute 属性および TimestampAttribute 属性でも、ドメイン サービス メタデータでの適用先のクライアント プロパティまたはクラスに RoundtripOriginalAttribute が表示されます。この実装を行うと、同時実行チェックの対象になるメンバーのみを指定できるため、アプリケーションのパフォーマンスを最適化できます。詳細については、次を参照してください。
注 : |
---|
KeyAttribute がエンティティ型のプロパティに適用された場合、プロジェクトがビルドされるときにクライアントで生成される対応するプロパティに RoundtripOriginalAttribute が追加されます。したがって、新しいドメイン サービス クラスの追加ウィザードを使用してデータベース ソースから生成されたドメイン サービスでは、これがエンティティ キーとして機能するプロパティの既定の動作になります。 |
RoundtripOriginalAttribute が適用されると、データ アクセス層は、データが取得されたときに記録されたデータ ソースの元の値を、データ ソースのデータの現在の値と比較します。値が同じ場合、ストアのデータは変更されていないため、そのデータはデータ アクセス層で更新または削除されます。データが変更されている場合は、競合が発生し、OptimisticConcurrencyException がスローされます。現在のデータを保持しなくなったエンティティの EntityConflict プロパティに、競合に関する情報が格納されます。
クライアントで更新または削除できるエンティティのメンバーに ExcludeAttribute 属性を適用する場合、オプティミスティック同時実行チェックでそのメンバーを使用することはできません。そのメンバーを除外すると、メンバーの元の正しい値が格納されず、更新操作は常に失敗します。詳細については、「方法: メタデータ クラスを追加する」を参照してください。
OptimisticConcurrencyException の処理
オブジェクトがキャッシュに追加された後またはキャッシュ内で更新された後、オブジェクト キャッシュのデータ変更がデータ ソース内の変更と競合すると、トランザクション全体がロールバックされます。OptimisticConcurrencyException が発生した場合、競合を解決するためにオブジェクト データ内のデータを維持するか (ClientWins)、オブジェクト キャッシュ内のデータをデータ ソースのデータで更新するか (StoreWins) を指定する必要があります。この方法の詳細については、「変更の保存と同時実行制御の管理」を参照してください。