user53791
user53791

Reputation:

With NHibernate and Transaction do I rollback on commit failure or does it auto rollback on single commit?

I've built the following Dispose method for my Unit Of Work which essentially wraps the active NH session & transaction (transaction set as variable after opening session as to not be replaced if NH session gets new transaction after error)

 public void Dispose()
    {
        Func<ITransaction,bool>  transactionStateOkayFunc = 
            trans => trans != null && trans.IsActive && !trans.WasRolledBack;

        try {
            if(transactionStateOkayFunc(this.transaction))
            {
                    if (HasErrored)
                    {
                        transaction.Rollback();
                    }
                    else
                    {
                        try
                        {
                            transaction.Commit();
                        } catch (Exception)
                        {
                            if(transactionStateOkayFunc(transaction)) transaction.Rollback();
                            throw;
                        }
                    }
                }
        } finally
        {
            if(transaction != null) transaction.Dispose();
            if(session.IsOpen) session.Close();
        }

I can't help feeling that code is a little bloated, will a transaction automatically rollback is a discrete Commit fails in the case of non-nested transactions?

Will Commit or Rollback automatically Dipose the transaction? If not will Session.Close() automatically dispose the associated transaction?

Upvotes: 6

Views: 4015

Answers (1)

Oskar Berggren
Oskar Berggren

Reputation: 5629

Dispose(), if available, should always be called.

For NHibernate's transaction, Dispose() will trigger rollback unless Commit() has already been called. You do not need to call Rollback() if Commit() errors out. Though IMHO you should still call Dispose(), if only to follow the pattern.

For session, asking "does Close() call Dispose()?" is sort of backwards. I "suspect" they might be equivalent, but it is good form to always call its Dispose(). When doing so, you do not need to call Close() separately.

Upvotes: 5

Related Questions