In the ORM that I created, I implemented a locking mechanism. Each type of object, for example Product, Customer, etc., has 2 additional fields: "LockedBy (int)" and "LockedAt (datetime)".
LockedBy contains the identifier of the user who locked the object, and lockedAt contains the timestamp at which it was locked.
So, when the user wants to start editing the entity, the code goes through this process:
Get an object from the database, '1' is the ProductID
Product p = new Product(1);
Lock object for current user
entity.Lock();
To save / fix the object in the database, Save () calls the LockCheck () function, which returns true if the registered user has permission to save the object.
entity.Save();
The user has permission to save the object if:
(LockedBy < 0 || LockedBy == LoggedInUser.UserID || LockedAt < DateTime.Now.AddMinutes(-30))
Note. Users can edit objects that were locked more than 30 minutes ago. If another user has an entity open (on the editing screen), then every 15 minutes it pops up and asks if the user remains there, if so, then he makes a request that increases LockedAt to Now (for example, rolling lock)
At this moment, no other user can edit this object!
The code / user can freely edit this object as much as he wants, and be sure that he has not changed behind him :)
As soon as the user has stopped editing code calls:
entity.Unlock()
then
entity.Save()
this frees the object for other users to edit it