2010-09-16 28 views
5

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#

Retryable actions in C#

Respuesta

6

Este:

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

... es completamente inútil. Si lo único que haces cuando "manejas" la excepción es ignorarla y guardarla de todos modos, simplemente debes desactivar la concurrencia optimista; está escribiendo código para trabajar en una función opcional.

Así que, sí, yo diría que la documentación no te está dando buenos consejos aquí.

Su código de UI propuesto es una solución mejor.