问题描述
评估.NET实体框架我试图找到正确的方式来处理并发更新与乐观并发模式。
Evaluating the .NET Entity Framework I try to find the right patterns to handle concurrent updates with optimistic concurrency mode.
在文档和其他许多地方我看到了下面的模式
In the documentation and many other places I see the following pattern:
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
我看到下面的问题,这
I see the following problems with this
- 自动实现后进胜利,而不是使用乐观模式
- 这是不健壮:.REFRESH和.SaveChanges之间的并发变化可能会造成新的OptimisticConcurrencyException
这是正确的,还是我失去了一些东西?
在一个UI,我通常让用户解决并发冲突:
In a UI I normally let the user resolve the concurrency conflict:
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
在业务逻辑我通常使用围绕整个业务事务重试循环(读取和更新):
In business logic I normally use a retry loop around the whole business transaction (reading and updating):
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我打算封装循环:
With EF I plan to encapsulate the loop:
ExecuteOptimisticSubmitChanges(Of EFConcurrencyTest.ConcurrencyTestEntities)(
Sub(ctx)
ctx.Inventories.First.QuantityInStock += 1
System.Threading.Thread.Sleep(3000) 'Cause conflict
End Sub)
请参阅:
在C#可重试动作
推荐答案
本:
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")
...是完全没有意义的。如果你这样做,当你处理唯一的例外是忽略它和保存,无论如何,你应该只把乐观并发关闭;你写code,以解决一个可选功能。
...is completely pointless. If the only thing you do when you "handle" the exception is to ignore it and save anyway, you should just turn optimistic concurrency off; you're writing code to work around an optional feature.
所以,是的,我想说的文档不给你在这里很好的建议。
So, yes, I'd say the documentation is not giving you good advice here.
您提出的UI code是一个更好的解决方案。
Your proposed UI code is a better solution.
这篇关于处理实体框架OptimisticConcurrencyException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!