处理实体框架OptimisticConcurrencyException

Pet*_*inl 5 .net entity-framework

评估.NET实体框架我尝试使用乐观并发模式找到正确的模式来处理并发更新.

文档和许多其他地方我看到以下模式:


Try
  ' Try to save changes, which may cause a conflict. 
  Dim num As Integer = context.SaveChanges()
  Console.WriteLine("No conflicts. " & num.ToString() & " updates saved.")
Catch generatedExceptionName As OptimisticConcurrencyException
  ' Resolve the concurrency conflict by refreshing the 
  ' object context before re-saving changes. 
  context.Refresh(RefreshMode.ClientWins, orders)

  ' Save changes. 
  context.SaveChanges()
  Console.WriteLine("OptimisticConcurrencyException handled and changes saved")
End Try

我看到了以下问题

  • 它会自动实现last-in-wins而不是使用乐观模式
  • 它不健壮:.Refresh和.SaveChanges之间的并发更改会导致新的OptimisticConcurrencyException

这是正确的,还是我错过了什么?

在UI中,我通常让用户解决并发冲突:


Try
   _ctx.SaveChanges()
Catch ex As OptimisticConcurrencyException
   MessageBox.Show("Data was modified by another User." & vbCrLf &
   "Click 'Refresh' to show the current values and reapply your changes.",
   "Concurrency Violation", MessageBoxButton.OK)
End Try

在业务逻辑中,我通常使用围绕整个业务事务(读取和更新)的重试循环:


Const maxRetries = 5, retryDelayMs = 500
For i = 1 To maxRetries
    Try
        Using ctx As New EFConcurrencyTest.ConcurrencyTestEntities
            ctx.Inventories.First.QuantityInStock += 1
            System.Threading.Thread.Sleep(3000) 'Cause conflict
            ctx.SaveChanges()
        End Using
        Exit For
    Catch ex As OptimisticConcurrencyException
        If i = maxRetries Then Throw
        System.Threading.Thread.Sleep(retryDelayMs)
    End Try
Next

使用EF我打算封装循环:


ExecuteOptimisticSubmitChanges(Of EFConcurrencyTest.ConcurrencyTestEntities)(
    Sub(ctx)
        ctx.Inventories.First.QuantityInStock += 1
        System.Threading.Thread.Sleep(3000) 'Cause conflict
    End Sub)

看到:

C#中的功能乐观并发

C#中的可重试动作

Cra*_*ntz 6

这个:

Catch ex As OptimisticConcurrencyException
  ' Resolve the concurrency conflict by refreshing the 
  ' object context before re-saving changes. 
  context.Refresh(RefreshMode.ClientWins, orders)

  ' Save changes. 
  context.SaveChanges()
  Console.WriteLine("OptimisticConcurrencyException handled and changes saved")
Run Code Online (Sandbox Code Playgroud)

......完全没有意义.如果你"处理"异常时唯一要做的就是忽略它并保存,你应该只关闭乐观并发; 您正在编写代码来解决可选功能.

所以,是的,我会说文档在这里没有给你很好的建议.

您提出的UI代码是更好的解决方案.