The following is a representative snippet of my code where an unexpected, at least on my part, exception is being thrown at the transaction.Rollback()
statement.
The exception is of type NHibernate.TransactionException
and the message is "Transaction not connected, or was disconnected." And the stack trace looks like this: NHibernate.Transaction.AdoTransaction.CheckNotZombied() at NHibernate.Transaction.AdoTransaction.Rollback()
.
IEmployeeService employeeService = new EmployeeService(session);
var people = ReadFromFile('c:\temp.csv');
for (var person in people)
{
ITransaction transaction = session.BeginTransaction();
try
{
employeeService.Update(person);
employeeService.CheckForRecursion();
transaction.Commit();
}
catch(Exception exp)
{
if (!transaction.WasRolledBack)
transaction.Rollback();
}
}
The CheckForRecursion uses some SQL to look for any recursion introduced by the last update, if so I want to undo. When recursion has been introduced then an exception bubbles up from SQL, rightly so, and I catch it and attempt to rollback. That's when I encounter the error.
I have wrapped the rollback in a try catch so the whole thing can carry on but I see the same exception on each subsequent iteration of the for loop.
Ideas? Is this pattern correct?
Why don't you just dispose the transaction?
using (ITransaction transaction = session.BeginTransaction())
{
employeeService.Update(person);
employeeService.CheckForRecursion();
transaction.Commit();
}
When an exception occurs, you should destroy the session. The changes had been made on the person, where it is not undone. When it can't be stored, it is not valid in memory.