处理Entity Framework的OptimisticConcurrencyException

5
我尝试评估.NET Entity Framework并寻找处理乐观并发模式下的并发更新的正确模式。
文档和许多其他地方,我看到以下模式:
尝试 ' 尝试保存更改,可能会引起冲突。 Dim num As Integer = context.SaveChanges() Console.WriteLine("没有冲突。" & num.ToString() & "个更新已保存。") Catch generatedExceptionName As OptimisticConcurrencyException ' 通过在重新保存更改之前刷新对象上下文来解决并发冲突。 context.Refresh(RefreshMode.ClientWins, orders)
' 保存更改。 context.SaveChanges() Console.WriteLine("OptimisticConcurrencyException已处理并保存更改") End Try
我认为存在以下问题:
它自动实现了最后一个胜出而不是使用乐观模式
它不够健壮:.Refresh和.SaveChanges之间的并发更改可能会导致新的OptimisticConcurrencyException
这是正确的吗?还是我漏掉了什么?
在UI中,我通常让用户解决并发冲突:
尝试 _ctx.SaveChanges() 捕获 OptimisticConcurrencyException 异常 MessageBox.Show("数据已被其他用户修改。" & vbCrLf & "点击 '刷新' 显示当前值并重新应用您的更改。", "并发冲突", MessageBoxButton.OK) 结束尝试

在业务逻辑中,我通常会在整个业务交易(读取和更新)周围使用重试循环:
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) '引起冲突
    End Sub)

请查看:

C#中的函数式乐观并发

C#中可重试的操作

1个回答

6

This:

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")

...是完全没有意义的。如果你在“处理”异常时唯一要做的事情就是忽略它并保存,那么你应该关闭乐观并发;你正在编写代码以解决一个可选功能。

所以,是的,我认为文档在这里没有给出好的建议。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接