Gui
Gui

Reputation: 9823

NHibernate - Is ITransaction.Commit really necessary?

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

Upvotes: 2

Views: 5268

Answers (3)

Diego Mijelshon
Diego Mijelshon

Reputation: 52753

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 important 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.

Upvotes: 9

Hannoun Yassir
Hannoun Yassir

Reputation: 21232

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;
        }
    }
}

Upvotes: 1

VoodooChild
VoodooChild

Reputation: 9784

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

Upvotes: 3

Related Questions