オプティミスティック コンカレンシー:概要
[アーティクル] 2023/06/08
11 人の共同作成者
フィードバック
この記事の内容
例
競合の検出と解決のチェック リスト
競合の発見と解決をサポートする LINQ to SQL の型
関連項目
LINQ to SQL はオプティミスティック コンカレンシーをサポートします。 LINQ to SQL のドキュメントでオプティミスティック コンカレンシーの説明に使用されている用語を次の表に示します。
テーブルを展開する
用語
説明
コンカレンシー
2 人以上のユーザーがデータベースの同じ行を同時に更新しようとした状況のことです。
コンカレンシーの競合
2 人以上のユーザーが、行の中の 1 つまたは複数の列に対し、互いに競合する値を送信しようとした状況のことです。
コンカレンシー制御
コンカレンシーの競合を解決するために使用する手法のことです。
オプティミスティック コンカレンシー
他のトランザクションが行の値に変更を加えていないかどうかをまず調べたうえで変更の送信を許可する手法のことです。 これと対照的なのが "ペシミスティック コンカレンシー制御 " で、レコードをロックすることでコンカレンシーの競合を防ぎます。 "オプティミスティック " (楽観的) という名前が付いているのは、トランザクションどうしが競合する可能性は小さいものと見なす方法であるためです。
競合の解決
データベースを再度クエリしてから相違点を調整することによって競合する項目を更新する処理のことです。 オブジェクトを更新するときには、LINQ to SQL の変更トラッカーによって、以下のデータが記録されます。 - データベースからもともと取得され、更新チェックに使用された値。 - その後のクエリで取得された新しいデータベース値。 次に LINQ to SQL は、オブジェクトが競合しているかどうか (つまり 1 つまたは複数のメンバー値が変更されているかどうか) を判断します。 オブジェクトが競合している場合、LINQ to SQL では次に、どのメンバーが競合しているかが判断されます。 LINQ to SQL が見つけたメンバーの競合は、競合の一覧に追加されます。
LINQ to SQL のオブジェクト モデルで "オプティミスティック コンカレンシーの競合" が発生するのは、次の 2 つの条件が両方とも成り立つ場合です。
この競合を解決するためには、オブジェクトのどのメンバーが競合しているかを判別し、どのように対処するかを決定することが必要です。
次のシナリオは、ユーザー 1 が、更新の手始めとして、データベースの行をクエリした状況です。 ユーザー 1 が取得した行には、Alfreds、Maria、および Sales という値が入っています。
ユーザー 1 は、Manager 列の値を Alfred に、また Department 列の値を Marketing に、それぞれ変更しようと考えています。 しかし、ユーザー 1 がその変更を発行する前に、ユーザー 2 がデータベースに変更を送信しました。 その結果、Assistant 列の値は Mary に、また Department 列の値は Service に、それぞれ変更されました。
ここで、ユーザー 1 が変更を送信しようとすると、送信は失敗し、ChangeConflictException 例外がスローされます。 このような結果になるのは、データベースの Assistant 列と Department 列の値が、予期した値と異なるためです。 Assistant 列と Department 列を表すメンバーが競合しています。 この状況をまとめると次の表のようになります。
テーブルを展開する
State
管理者
Assistant
Department
元の状態
Alfreds
Maria
Sales
ユーザー 1
Alfred
Marketing
ユーザー 2
Mary
サービス
このような競合は、いくつかの方法で解決できます。 詳細については、変更の競合を管理する 」を参照してください。
競合の検出と解決は、さまざまな詳細レベルで行うことができます。 極端な方法としては、すべての競合を 3 つの方法 (RefreshMode を参照) のいずれかで 1 つで解決し、それ以外の考慮を一切加えないという方法もあります。 正反対の方法としては、競合している各メンバーについて、それぞれの競合の種類ごとに、特定の処理を指定するという方法もあります。
競合の発見と解決をサポートする LINQ to SQL の型
LINQ to SQL で、オプティミスティック コンカレンシーの競合の解決をサポートするクラスと機能を以下に示します。