Reputation: 85785
I have an int column for each revision I make of an item. I want to get the last revision number for that item and increment it by one and save it to this new revision I am making.
I am a bit concerned that I will run into a issue where the same item is being revised at the same time and all of a sudden I got 2 revisions with the same number.
Example
Item1 Revision 1
Item1 Revision 2
Item2 Revision 1
Item2 Revision 2
Item3 Revision 1
the above may already be in my database. Now I want to add another revision to Item1. It should be Revision "3".
I want to find that Item 1 had a last revision of "2" and then use that to figure out tit should be revision "3".
I am worried though that multiple people will start revision Item 1 and submit around the same time and that I will get revision 2 back in memory for all 3 people revising Item 1 and I will end up with
Item1 Revision 1
Item1 Revision 2
Item1 Revision 3
Item1 Revision 3 (should be 4)
Upvotes: 1
Views: 329
Reputation: 5629
Create a unique key over the combination of primary key and revision number. That will at least prevent duplication in the DB.
The remaining issue is if you expect this parallel edit to happen often - if so you would probably want to add some mechanism to detect it earlier to save on user time. One method is to use pessimistic locking on the original row.
Upvotes: 0
Reputation: 123861
EDIT: 1) In case of updating the same row
There is an NHibernate feature: the Version
or Timestamp
property and the powerful management arround it. Try to read here: When to use Nhibernate ? for more details. Extract
...entity instance has a version, which can be a number or a timestamp. Hibernate increments an object’s version when it’s modified, compares versions automatically, and throws an exception if a conflict is detected. Consequently, you add this version property to all your persistent entity classes to enable optimistic locking. ... The version number is just a counter value—it doesn’t have any useful semantic value.
NHibernate documentation:
So, when you will use Version you will gain:
You can then use more standard features (e.g. Interceptors) and audit all changes on update into different table... with the current Version number.
Summary: Versioning system in NHibernate will not solve everything. You will be provided with StaleExceptions... and have to handle them. BUT, you can be sure, that only one Version at time was stored with the same Version number
EDIT: 2) tracking new change as the new row
Please, take this as a suggestion, based on our approach. This is how we are implementing changes as a Audit tracking system
The business object e.g. IAuditable is defined as:
public class Article : IAuditable
{
public virtual int ID { get; set; }
public virtual string Text { get; set; }
...
// if possible to move it to base for more Business Objects
// public virtual IList<IHistory> History { get; set; }
public virtual IList<ArticleHistory> History { get; set; }
}
Whenever There is an update, the Article itslef is updated, and new ArticleHistory instance is created. Using HiLo generator for its ID, it is correctly inserted even in a web-farm.
This approach allows to work with up-to-date instance of Article, improve performance (History is in separated table) and supports AOP (history tracking is turned on/off via Injecting the AuditAOPFilter. Only on a detail we load the History collection.
This is an suggestion. I can understand that this does not suite to your scenario (and does not answer the question).
Upvotes: 1