Практическое руководство. Разрешение конфликтов за счет слияния со значениями баз данных
Чтобы согласовать различия между ожидаемыми и фактическими значениями базы данных до повторной отправки изменений, можно воспользоваться KeepChanges для слияния значений базы данных с текущими значениями члена клиента. Дополнительные сведения см. в разделе "Оптимистическое параллелизм". Обзор.
Примечание.
Во всех случаях запись на клиенте сначала обновляется путем извлечения обновленных данных из базы данных. Это действие гарантирует успешное выполнение следующей попытки обновления при тех же проверках параллелизма.
Пример
В данном сценарии, когда Пользователь1 пытается отправить изменения, возникает исключение ChangeConflictException, поскольку Пользователь2 в это время изменил столбцы "Помощник" и "Отдел". Эта ситуация представлена в следующей таблице.
State | Manager | Помощник | Отдел |
---|---|---|---|
Исходное состояние базы данных при отправке запросов Пользователем1 и Пользователем2. | Алексеи | Мария | Продажи |
Пользователь1 готовится отправить изменения. | Алексей | Маркетинг | |
Пользователь2 уже отправил изменения. | Mary | Service |
Пользователь1 решает устранить этот конфликт путем объединения значений базы данных с текущими значениями члена клиента. Ожидаемый результат: значения базы данных будут переопределены только при изменении значения текущим набором изменений.
При устранении Пользователем1 конфликта с помощью KeepChanges результат в базе данных будет соответствовать данным в следующей таблице.
State | Manager | Помощник | Отдел |
---|---|---|---|
Новое состояние после устранения конфликта. | Алексей (от Пользователя1) |
Mary (от Пользователя2) |
Маркетинг (от Пользователя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)