Handling Entity Framework OptimisticConcurrencyException

Assessing the .NET Entity Framework I'm trying to find the right patterns for handling concurrent updates with optimistic concurrency mode.

In the documentation and in 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

  • it automatically implements the "last in gain" instead of using the optimistic mode.
  • it is not reliable: simultaneous changes between .Refresh and .SaveChanges may cause a new OptimisticConcurrencyException

Is this right, or am I missing something?

In the user interface, I usually allow the user to 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

- - ( ):

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)

:

concurrency #

#

+5
1

:

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

... . , , "" , , concurrency; , .

, , , .

.

+6

All Articles