4

In my project, users will be able to edit some sets of data as much as needed. However, due to the project specification, only one user can edit a certain data set/ access the data set's edit page at a time. So if user A is editing Data Set 1, user B must not be able to access the edit page of Data Set 1 so long as user A is at that page, and vice versa.

I did a bit of reading and Pessimistic Concurrency seems to be what I'm looking for, where a page gets "locked" out until the user inside that page leaves, which explains my title.

I am still fairly new to ASP.NET and web development in general. I would like to ask if I'm heading in the right direction to approach my problem, How could I implement it in my project (I only keep seeing samples for Optimistic Concurrency) and if there are other ways, which I have not encountered, To approach my problem.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
JeanDeus
  • 85
  • 1
  • 7
  • Pessimistic concurrency should *not* be used if one doesn't fully understand what it is (keeping a transaction open for the entire duration of a complex operation) the consequences because it seriously degrades performance because it *blocks* any *queries* that try to affect the locked row. In your case, you are describing a checkin/checkout scenario that can be implemented with a row flag or a checkin/out table, *not* a concurrency scenario. It's not even possible to keep a database transaction open in a web application - loading the edit page and submitting changes are different requests – Panagiotis Kanavos Sep 02 '15 at 10:46

1 Answers1

5

First of all I'd say that your question is about the database and EF, not ASP.NET MVC. By the way, There are two basic types of concurrency control:

Pessimistic concurrency which locks data between the time that requested by a user and a time he saves changes so that no other users can save changes the same data during that time.

Optimistic concurrency which locks nothing and assumes that the second user is attempted to change the data won't conflict with changes saved by the first user, but if there is a conflict the second user's changes are aborted and only the first user's changes remain.
EF doesn't support Pessimistic concurrency directly.

So I think the best option for you is Optimistic concurrency which EF does support, which as you probably know, it works by inspecting pre- and post-update data to determine if user B modified it between the time user A retrieved it and updated it. If it changed then user A's modifications are discarded, If not then user A's modifications are updated into the database.

To implement Optimistic concurrency you can simply define a RowVersion property for your model:

public byte[] RowVersion { get; set; }

and in your model's configuration you should tell EF that it has the behaviour of a Row Version in property:

Property(p => p.RowVersion).IsRowVersion();

Now if user A retrieves the data, and user B retrieves same data and user B saves the changes before user A saves his changes, user A's changes are discarded and an exception is thrown:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh YourModelName entries.

More info.

Sirwan Afifi
  • 10,654
  • 14
  • 63
  • 110