Reputation:
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
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