问题
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?
回答1:
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.
回答2:
I got this error when a trigger on the table raised an error. I fixed the trigger and the transaction error went away.
I have the NHibernate generated SQL display in the output window so I took the last generated sql statement and ran it in a query tool. The trigger raised an error about truncating string values.
Here's an example of a table with a trigger which will cause this sort of error in NHibernate.
CREATE TABLE myTable (
id int IDENTITY(1,1) NOT NULL,
ThisIsA10CharField varchar(10),
CONSTRAINT myTable_pk PRIMARY KEY CLUSTERED (id));
GO
CREATE TRIGGER myTable_MakeError ON myTable AFTER INSERT AS
BEGIN
INSERT INTO myTable (ThisIsA10CharField) values ('this will raise a truncate error')
END
GO
INSERT INTO mytable (ThisIsA10CharField) values ('x')
Msg 8152, Level 16, State 14, Procedure myTable_MakeError, Line 4 String or binary data would be truncated. The statement has been terminated.
来源:https://stackoverflow.com/questions/14341509/nhibernate-and-transactions-transaction-not-connected-or-was-disconnected