tags:

views:

132

answers:

3

Hi

I've just start studying NHibernate 2 days ago, and I'm looking for a CRUD method that I've written based on an tutorial. My insert method is:

        using (ISession session = Contexto.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            session.Save(noticia);
            transaction.Commit();
            session.Close();
        }

The complete code of "Contexto" is here: http://codepaste.net/mrnoo5

My question is: Do i really need to use ITransaction transaction = session.BeginTransaction() and transaction.Commit();?

I'm asking this because I've tested run the web app without those two lines, and I've successfully inserted new records.

If possible, can someone explain me too the purpose of Itransaction and the method Commit?

Thanks

+1  A: 

Well you call Commit() on your transaction it saves all the changes to the database.

Do i really need to use ITransaction transaction = session.BeginTransaction() and transaction.Commit();?

yes it is considered good practice using transactions for everything even simple reads.

tested run the web app without those two lines, and I've successfully inserted new records.

that because the session will commit the changes when it is disposed at the end of the using statement.

anyway this is how i would right the save :

using (ISession session = Contexto.OpenSession())
{
    using (ITransaction transaction = session.BeginTransaction())
    {
        try
        {
            session.Save(noticia);
            transaction.Commit();
        }
        catch(HibernateException)
        {
            transaction.Rollback();
            throw;
        }
    }
}
Yassir
+1, What happens if you have trans.commit, but no sess.Close? any thoughts
VoodooChild
@VoodooChild : when you commit the transaction all the changes in the session will be committed to the database. even if there is no session.Close()
Yassir
@Yassir, the code inside your catch is redundant. The transaction is rolled back if the `using` block is left without committing.
Diego Mijelshon
@Diego, I disagree you on this. What if there is a exception on trx.Commit()? and what if in the catch you don't do a trx.Rollback()? are you saying that somehow it is rolled back? If so provide a source that verifies this, please.
VoodooChild
It's all here: https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Transaction/AdoTransaction.cs BTW, look at the sample code created by all the NH experts (Oren, Fabio, etc...). You'll never find code like that. Why? Because it's redundant.
Diego Mijelshon
@Yassir, that proves my point. It's the correct pattern: explicit transaction/commit, **implicit rollback**.
Diego Mijelshon
A: 

ITransaction transaction = session.BeginTransaction() is not necessary as you found out by testing.

But imagine this, what happens when your session throws an exception? how would you get back your changes to the database?

The following is quote from Nhib...

A typical transaction should use the following idiom:

ISession sess = factory.OpenSession();
ITransaction tx; 
try 
{ 
    tx = sess.BeginTransaction(); //do some work ... 
    tx.Commit(); 
} 
catch (Exception e) 
{ 
    if (tx != null) 
    tx.Rollback(); 
    throw;
} 
finally 
{ 
    sess.Close(); 
}

If the ISession throws an exception, the transaction must be rolled back and the session discarded. The internal state of the ISession might not be consistent with the database after the exception occurs. NHibernate.ISessionFactory

VoodooChild
I'll try to read more about exceptions and how to roll back the transiction and discard the session.Thanks from Portugal ;)
Guilherme Cardoso
Transactions should ALWAYS be used.
Diego Mijelshon
I thought it was pretty clear from my answer that it should be used. always!
VoodooChild
+1  A: 

This is the proper generic NHibernate usage pattern:

using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
    //Do the work here
    transaction.Commit();
}

All of that is required to ensure everything works as expected (unless you use additional infrastructure)

Closing the session or doing anything with the transaction besides committing is redundant, as the Dispose methods of the session and the transaction takes care of cleanup, including rollback if there are errors.

It's importat to note than doing anything with the session after an exception can result in unexpected behavior, which is another reason to limit explicit exception handling inside the block.

Diego Mijelshon
+1, thanks...I will have a look as soon as I can.
VoodooChild