Evaluar .NET Entity Framework Intento encontrar los patrones correctos para manejar las actualizaciones concurrentes con el modo de concurrencia optimista.Manejar Entity Framework OptimisticConcurrencyException
En los otros documentation y muchos lugares que ver el siguiente patrón:
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
veo los siguientes problemas con este
- se implementa de forma automática último en entrar, victorias en lugar de utilizar optimista modo
- no es robusto: los cambios concurrentes entre .Refresh y .SaveChanges pueden causar una nueva OptimisticConcurrencyException
¿Es correcto o me falta algo?
En una interfaz de usuario que normalmente permiten al usuario a resolver el conflicto de concurrencia:
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
En la lógica de negocio que normalmente uso un bucle de reintento alrededor de toda la transacción comercial (lectura y actualización):
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
W EF ITH planeo para encapsular el bucle:
ExecuteOptimisticSubmitChanges(Of EFConcurrencyTest.ConcurrencyTestEntities)( Sub(ctx) ctx.Inventories.First.QuantityInStock += 1 System.Threading.Thread.Sleep(3000) 'Cause conflict End Sub)
Ver:
Functional Optimistic Concurrency in C#