オプティミスティック同時実行の概要 (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 つまたは複数の更新チェック値が更新されている。

この競合を解決するためには、オブジェクトのどのメンバーが競合しているかを判別し、どのように対処するかを決定することが必要です。

メモメモ

オプティミスティック同時実行のチェックに関与するのは、Always または WhenChanged として割り当てられているメンバーのみです。Never と指定されているメンバーには、チェックは実行されません。詳細については、「UpdateCheck」を参照してください。

次のシナリオは、ユーザー 1 が、更新の手始めとして、データベースの行をクエリした状況です。 ユーザー 1 が取得した行には、Alfreds、Maria、および Sales という値が入っています。

ユーザー 1 は、Manager 列の値を Alfred に、また Department 列の値を Marketing に、それぞれ変更しようと考えています。 しかし、ユーザー 1 がその変更を発行する前に、ユーザー 2 がデータベースに変更を送信しました。 その結果、Assistant 列の値は Mary に、また Department 列の値は Service に、それぞれ変更されました。

ここで、ユーザー 1 が変更を送信しようとすると、送信は失敗し、ChangeConflictException 例外がスローされます。 このような結果になるのは、データベースの Assistant 列と Department 列の値が、予期した値と異なるためです。 Assistant 列と Department 列を表すメンバーが競合しています。 この状況をまとめると次の表のようになります。

 

Manager

Assistant

Department

元の状態

Alfreds

Maria

Sales

ユーザー 1

Alfred

 

Marketing

ユーザー 2

 

Mary

Service

このような競合は、いくつかの方法で解決できます。 詳細については、「方法 : 変更の競合を管理する (LINQ to SQL)」を参照してください。

競合の検出と解決のチェック リスト

競合の検出と解決は、さまざまな詳細レベルで行うことができます。 極端な方法としては、すべての競合を 3 つの方法 (RefreshMode を参照) のいずれかで 1 つで解決し、それ以外の考慮を一切加えないという方法もあります。 正反対の方法としては、競合している各メンバーについて、それぞれの競合の種類ごとに、特定の処理を指定するという方法もあります。

競合の発見と解決をサポートする LINQ to SQL の型

LINQ to SQL で、オプティミスティック同時実行の競合の解決をサポートするクラスと機能を以下に示します。

参照

その他の技術情報

方法 : 変更の競合を管理する (LINQ to SQL)