Reputation: 2993
I have a project where multiple users may look at the same page of data at the same time, and make changes to it. Because of this, the lost update problem will occur.
I want to know if there are any frameworks or patterns to follow which will handle this gracefully. So if someone only changes one field in the view model, I'd like to update only this column in the database.
Currently I post the view model back to a controller, validate, and then automap to the Entity Framework class.
As a proper example, let's say my view model is as follows:
public class MyViewModel
{
public int Id { get; set; }
public int Num1 { get; set; }
public int Num2 { get; set; }
}
There is only 1 row in the database as follows:
Id = 1
Num1 = 10
Num2 = 20
This then gets read into the view model when the page is loaded.
If person A and Person B both use the website to browse to this record at the same time, they will both have 10 and 20 for Num1 and Num2 respectively on their screen.
Person A sets Num1 to 15 and presses save.
Person B then changes Num2 to 25 and presses save. However Person A's change of Num1 = 15 gets lost and overwritten by 10 from Person B's record, since the whole view model gets saved.
Does anyone have any web frameworks they can recommend which plan nicely with MVC which will avoid this issue?
Upvotes: 2
Views: 1657
Reputation: 33098
The other solution to this problem is removing your system from being a CRUD based system.
Some examples of these tools:
command architecture / CQRS
event sourcing:
Here's a rather 101 article on Event Sourcing/CQRS http://simon-says-architecture.com/2011/01/15/probably-the-most-powerful-cqrsevent-sourcing-platform-in-net/ much more information about these topics can be found here by searching for these concepts.
By moving to an architecture that is built on these you will send more focused objects. You said about person A updating Num1 and person B updating Num2, those shows those are likely discrete boundaries and that you should have a separate commands for update Num1 vs Num2. Unless you're going to implement these solutions on a field by field basis at some point you have to accept that there is concurrency access that cannot be solved except by a human involved merge process.
Num1 is 0, if user A updates Num1 to 5 and user B updates Num to 10 what is the correct answer? Is it 5? Is it 10? Is it 15? Only a human can determine this.
Upvotes: 0
Reputation: 2412
The best solution would likely be to use something like SignalR to update the other users' object as the model is updated: http://signalr.net/
A simpler/cruder implementation without much hassle could be something to this effect:
public class MyViewModel
{
public int Id { get; set; }
public int Num1 { get; set; }
public int Num2 { get; set; }
public int Num1Orig { get; set; }
public int Num2Orig { get; set; }
}
Include the _Orig as hidden fields in the view. Then on your post, get the current object from the DB, compare the new model value to the _Orig value and only update the entity object if it's changed.
Upvotes: 1