NH Prof documentation: Transaction and the second level cache
Another implication of not using explicit transactions with NHibernate is related ot the use of the second level cache.
NHibernate goes to great lengths in order to ensure that the 2nd level cache shows a consistent view of the database. In order to do that it is defering all 2nd level cache updates to the transaction commit. In that way, we can be sure that the data in the 2nd level cache is the one committed to the database.
Forgoing the use of explicit transactions has the effect of nulling the 2nd level cache. Here is an example that would make this clear:
using(var session = sessionFactory.OpenSession()) { var post = session.Get<Post>(1); // do something with post }
Even if the 2nd level cache is enabled for Post, it is still not going to be cached in the 2nd level cache. The reason is that until we commit a transaction, NHibernate will not update the cache with the values for the loaded entities.
This code, however, does make use of the 2nd level cache:
using(var session = sessionFactory.OpenSession()) using(var tx = session.BeginTransaction()) { var post = session.Get<Post>(1); // do something with post tx.Commit(); }
Comments
Interesting. Is this the solely reason to use transactions with selects or are there more reasons?
See my previous discussion on that.
nhprof.com/.../Alert
Dammit, I had already read that. I think I have a memory leak.
If you are always supposed to use transactions, then why doesn't NH do it implicitly for us?
Alberto,
Because implicit transactions are a very bad idea.
Maybe implicit is not the correct term, regarding your previous post.
What I meant was that if you are always supposed to use those 2 usings together, wouldn't it be better to merge them in one, and enforce the use of transactions at the uow level? Is this still a bad idea?
NHibernate is too low level to manage transactions internally
Well... all this stuff are enough to implement a TransactionProtection wrapper in our session-handling implementation ;)
code.google.com/.../...sactionProtectionWrapper.cs
In uNhAddIns there is one implemented for Castle.DynamicProxy (obviously)
When you say, //Do something with post...
I assume you mean changing the Post object you just received? If it was just a read I can't see why commiting the transaction makes any difference to the 2nd level cache?
Stuart,
Not really.
It can be anything.
NH can't know about that, so it doesn't put things to the cache, so it will only put it in the cache after commit.
If the entity has been marked mutable=false, would it make sense to automatically cache that? since it can't be changed? The Transaction doesn't make sense in that case.
Doesn't matter.
Trying to find edge cases would make the code more complex, commit the transaction, and good things will happen
Comment preview