Ayende @ Rahien

Unnatural acts on source code

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

alberto
01/10/2009 11:50 AM by
alberto

Interesting. Is this the solely reason to use transactions with selects or are there more reasons?

Ayende Rahien
01/10/2009 11:55 AM by
Ayende Rahien

See my previous discussion on that.

alberto
01/10/2009 12:07 PM by
alberto

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?

Ayende Rahien
01/10/2009 12:13 PM by
Ayende Rahien

Alberto,

Because implicit transactions are a very bad idea.

alberto
01/10/2009 02:23 PM by
alberto

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?

Ayende Rahien
01/10/2009 02:24 PM by
Ayende Rahien

NHibernate is too low level to manage transactions internally

Stuart C
01/12/2009 12:47 PM by
Stuart C

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?

Ayende Rahien
01/12/2009 12:57 PM by
Ayende Rahien

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.

Jafin
01/19/2009 05:46 AM by
Jafin

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.

Ayende Rahien
01/19/2009 05:54 AM by
Ayende Rahien

Doesn't matter.

Trying to find edge cases would make the code more complex, commit the transaction, and good things will happen

Comments have been closed on this topic.