0
votes

I have a windows service written in the .NET 4.0 framework that uses NHibernate enlisting in a distributed transaction talking to an Oracle database. Within our test environment the service encountered an error with the database which seems to have caused a problem with NHibernate closing the ADO.NET connection.

The entire call against NHibernate, from opening the session to disposing of it, is wrapped within a try/catch block that catches System.Exception but the error is not caught within that block.

I've included the stack trace from the windows event log below for reference.

I believe that the exception is being thrown in another thread (which the stack trace seems to refer to) which then propogates up and causes the windows service to crash.

My questions are:
1. If it is another thread, where does it come from (what starts it)?
2. Is there anything I can add to my code to make sure this exception does not escape and bring down the windows service?


Application: X
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: NHibernate.ADOException
Stack:
at NHibernate.Connection.ConnectionProvider.CloseConnection(System.Data.IDbConnection)
at NHibernate.Connection.DriverConnectionProvider.CloseConnection(System.Data.IDbConnection)
at NHibernate.AdoNet.ConnectionManager.CloseConnection()
at NHibernate.AdoNet.ConnectionManager.AfterTransaction()
at NHibernate.Impl.SessionImpl.AfterTransactionCompletion(Boolean, NHibernate.ITransaction)
at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory+<>c_DisplayClass1.b_0(System.Object, System.Transactions.TransactionEventArgs)
at System.Transactions.TransactionCompletedEventHandler.Invoke(System.Object, System.Transactions.TransactionEventArgs)
at System.Transactions.TransactionStatePromotedAborted.EnterState(System.Transactions.InternalTransaction)
at System.Transactions.InternalTransaction.DistributedTransactionOutcome(System.Transactions.InternalTransaction, System.Transactions.TransactionStatus)
at System.Transactions.Oletx.RealOletxTransaction.FireOutcome(System.Transactions.TransactionStatus)
at System.Transactions.Oletx.OutcomeEnlistment.InvokeOutcomeFunction(System.Transactions.TransactionStatus)
at System.Transactions.Oletx.OletxTransactionManager.ShimNotificationCallback(System.Object, Boolean)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)

1

1 Answers

0
votes

If it is another thread, where does it come from (what starts it)?

Inside NHibernate.Transaction.AdoNetWithDistributedTransactionFactory, there exists an event handler for System.Transactions.Transaction.TransactionCompleted. This event is fired on a thread pool thread by the .NET framework upon completion, as shown at the bottom of your stack trace.

Is there anything I can add to my code to make sure this exception does not escape and bring down the windows service?

The correct thing to do is hunt down exactly why the exception occurs. I haven't used Oracle, but didn't really have this particular issue dealing with DTC and SQL Server (though there are plenty of other ones). The source of the problem could be DTC or a bug in NHibernate.