Handle concurrency in Entity Framework

I am looking for a better way to handle concurrency when using the Entity Framework. The simplest and most recommended solution (also for the stack) is described here: http://msdn.microsoft.com/en-us/library/bb399228.aspx And it looks like this:

try { // Try to save changes, which may cause a conflict. int num = context.SaveChanges(); Console.WriteLine("No conflicts. " + num.ToString() + " updates saved."); } catch (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"); } 

But is that enough? What if something changes between Refresh () and the second SaveChanges ()? Will an OptimisticConcurrencyException be thrown?

EDIT 2:

I think this will be the final decision:

  int savesCounter = 100; Boolean saveSuccess = false; while (!saveSuccess && savesCounter > 0) { savesCounter--; try { // Try to save changes, which may cause a conflict. int num = context.SaveChanges(); saveSuccess = true; Console.WriteLine("Save success. " + num.ToString() + " updates saved."); } catch (OptimisticConcurrencyException) { // Resolve the concurrency conflict by refreshing the // object context before re-saving changes. Console.WriteLine("OptimisticConcurrencyException, refreshing context."); context.Refresh(RefreshMode.ClientWins, orders); } } 

I'm not sure if I understood how Refresh () works. Does it update the whole context? If so, why does it take additional arguments (object objects)? Or does it only update the specified objects? For example, in this situation, what should be passed as Refresh () is the second argument:

 Order dbOrder = dbContext.Orders.Where(x => x.ID == orderID); dbOrder.Name = "new name"; //here whole the code written above to save changes 

should it be dbOrder?

+4
source share
1 answer

Yes, even a second save can raise an OptimisticConcurrencyException if, as you say, something changes between Refresh() and SaveChanges() .

The above example is a very simple retry logic, if you need to retry more than once or resolve the conflict in a more complex way, you better create a loop that will repeat n times than nesting try / catch at more than one level.

+4
source

Source: https://habr.com/ru/post/1399387/


All Articles