I would like to use the "Many sessions with automatic versioning" approach to optimistic concurrency control e.g.:
Code:
// foo is an instance loaded by a previous Session
foo.Property = "bar";
session = factory.OpenSession();
transaction = session.BeginTransaction();
session.SaveOrUpdate(foo);
session.Flush();
transaction.Commit();
session.Close();
This implies that the object to be updated must be held in user state (i.e serialized to ViewState or saved in Session). However, in a scalable stateless web application, objects will not be preserved between requests. In this case each interaction with the database occurs in a new ISession that reloads all persistent instances from the database before manipulating them.
Unfortunately, it seems NHibernate does not support automatic versioning with completely reloading during each session. Ideally I would just store the object's version in viewstate during the first read. When the user decides to update, the persistent instance is reloaded from the database, and modified
including setting the version to what it was originally. (Essentially recreating the state of the object as it was during the first read - not as it might currently be in the database). Then when it is submitted back for an update the version value
stored in the instance is automatically made part of the where clause as usual.
Code:
//First Request (display the object in editing form)
session = factory.OpenSession();
foo = session.Load<Foo>(id);
TextBox1.Text =foo.Property;
ViewState["FooVersion"] = foo.Version;
session.Close();
//Meanwhile, another user updated this foo, and changes the version
//Next Request (PostBack)
session = factory.OpenSession();
foo = session.Load<Foo>(id);
foo.Property = TextBox1.Text;
foo.Version = (DateTime)ViewState["Version"];
transaction = session.BeginTransaction();
session.Update(foo);
session.Flush();
transaction.Commit();
session.Close();
//Now if the update query has the original version in the where clause, it will correctly fail since another user has modified foo since the original read.
Please let me know if this makes any sense in NHibernate. (This is how I have successfully implemented stateless optimistic locking using another O/R mapper, so I assume it should be possible wiht NH.)
Thanks