方法: データベース値とマージすることで競合を解決する
変更内容を再送信する前に、データベース内の予期した値と実際の値の違いを調整するために、KeepChanges を使用して、データベース内の値を現在のクライアント メンバー値とマージできます。 詳しくは、「オプティミスティック コンカレンシー: 概要) の下のステートメントを右クリックします。
Note
どの場合も、データベースから最新のデータを取得することで、まずクライアントのレコードが更新されます。 この処理によって、次の更新処理が同じコンカレンシー チェックで失敗することを防止できます。
例
このシナリオでは、ユーザー 1 が変更内容を送信しようとしたときに ChangeConflictException 例外がスローされます。途中でユーザー 2 が Assistant 列と Department 列を変更したためです。 次の表は、この状況を示しています。
State | 管理者 | Assistant | Department |
---|---|---|---|
ユーザー 1 およびユーザー 2 が照会した最初のデータベース状態 | Alfreds | Maria | Sales |
ユーザー 1 が送信しようとした変更内容 | Alfred | Marketing | |
ユーザー 2 が既に送信した変更内容 | Mary | サービス |
ユーザー 1 は、この競合を解決するために、データベース値を現在のクライアント メンバー値にマージすることに決めます。 その結果、現在の変更セットでも値が変更されているデータベース値のみが上書きされます。
ユーザー 1 が KeepChanges を使用して競合を解決すると、データベース内の結果は次の表のようになります。
State | 管理者 | Assistant | Department |
---|---|---|---|
競合解決後の新しい状態 | Alfred (ユーザー 1 の値) |
Mary (ユーザー 2 の値) |
Marketing (ユーザー 1 の値) |
次の例では、クライアントでも値が変更されている場合を除き、データベース値を現在のクライアント メンバー値にマージする方法を示しています。 個別のメンバーの競合に対する検査やカスタム ハンドリングは発生しません。
try
{
db.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
Console.WriteLine(e.Message);
// Automerge database values for members that client
// has not modified.
foreach (ObjectChangeConflict occ in db.ChangeConflicts)
{
occ.Resolve(RefreshMode.KeepChanges);
}
}
// Submit succeeds on second try.
db.SubmitChanges(ConflictMode.FailOnFirstConflict);
Try
db.SubmitChanges(ConflictMode.ContinueOnConflict)
Catch ex As ChangeConflictException
Console.WriteLine(ex.Message)
For Each occ As ObjectChangeConflict In db.ChangeConflicts
' Automerge database values into current for members
' that client has not modified.
occ.Resolve(Data.Linq.RefreshMode.KeepChanges)
Next
End Try
' Submit succeeds on second try.
db.SubmitChanges(ConflictMode.FailOnFirstConflict)