评估.NET实体框架我尝试使用乐观并发模式找到正确的模式来处理并发更新。
在documentation和其他许多地方,我看到以下模式:
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
我看到了这个
的以下问题这是正确的,还是我错过了什么?
在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)
见:
答案 0 :(得分: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")
......完全没有意义。如果你“处理”异常时唯一要做的就是忽略它并保存,你应该只关闭乐观并发;您正在编写代码来解决可选功能。
所以,是的,我说文档在这里没有给你很好的建议。
您建议的UI代码是更好的解决方案。