Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimistic concurrency model in Entity Framework and MVC

I have the following update code in the ASP.NET MVC controller:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Person(int id, FormCollection form)
{
  var ctx = new DB_Entities(); // ObjectContext
  var person = ctx.Persons.Where(s => s.Id == id).FirstOrDefault(); 
  TryUpdateModel(person, form.ToValueProvider()); 
  ctx.SaveChanges(); 
  return RedirectToAction("Person", id);
}

However, this update code is Last-Writer-Wins. Now I want to add some concurrency control. The Person table already has the SQL timestamp column. Do I have to send the timestamp value to the client as the hidden value and process it manually in the post back? Or is there a a standard pattern in Entity Framework to do this?

Thanks.

like image 301
Hengyi Avatar asked Oct 10 '10 01:10

Hengyi


People also ask

What is optimistic concurrency in Entity Framework?

EF Core implements optimistic concurrency control, meaning that it will let multiple processes or users make changes independently without the overhead of synchronization or locking. In the ideal situation, these changes will not interfere with each other and therefore will be able to succeed.

How concurrency is handled in MVC?

Test concurrency handlingChange a field in the first browser tab and click Save. The browser shows the Index page with the changed value. Click Save again. The value you entered in the second browser tab is saved along with the original value of the data you changed in the first browser.

What is concurrency check in Entity Framework?

Concurrency conflicts occur when one user retrieves an entity's data in order to modify it, and then another user updates the same entity's data before the first user's changes are written to the database.

What are the two approaches for concurrency tokens that the EF provides state which approach is not recommended?

EF provides two approaches for concurrency tokens: Applying [ConcurrencyCheck] or IsConcurrencyToken to a property on the model. This approach is not recommended. For more information, see Concurrency Tokens in EF Core.


1 Answers

First you need to define which property or properties will be used to perform the concurrency check, because concurrency is defined on a property-by-property basis in the Entity Framework. ConcurrencyMode is used to flag a property for concurrency checking and can be found in the Entity Object Properties window (just right click on Person entity in your model). Its options are None, which is the default, and Fixed.

During a call to SaveChanges, if a field has been changed in the DB since the row was retrieved, EF will cancel the Save and throw an OptimisticConcurrencyException if we set that field's ConcurrencyMode to Fixed.

Under the hood, EF includes that field's value in the Update or Delete SQL statement that is being Submitted to the data store as a WHERE clause.

If you want to have Optimistic Concurrency on all properties, just set TimeStamp property ConcurrencyMode to Fixed you will get an OptimisticConcurrencyException if any field's value within the table get changed (instead of setting it to Fixed on every single property).

EDIT
As per Craig comment below, you need to persist the TimeStamp in the view and read it back into Person object and the rest will be taken care of by EF if you set the ConcurrencyMode to fixed on the TimeStamp property. You can of course try to handle OptimisticConcurrencyException that could be thrown by EF and there are ways to recover from this exception, if you are interested.

like image 156
Morteza Manavi Avatar answered Oct 17 '22 02:10

Morteza Manavi