我尝试评估.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) 结束尝试 在业务逻辑中,我通常会在整个业务交易(读取和更新)周围使用重试循环:
在文档和许多其他地方,我看到以下模式:
尝试 ' 尝试保存更改,可能会引起冲突。 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)
请查看: