I encountered same problem today when running a regression test from home. The thing was working while I at the office and for some reason started getting this error once I was home. I was getting this pretty consistently and found this thread. We're only calling commit/rollback if transaction.IsActive so that pretty much rules out the transaction commited/aborted/not openned so thought I would debug the issue and see what is going on. I don't have the NH symbols or source on my machine so I couldn't step into the NH but I could see in the debugger that trans != null && trans.Connection == null thus the exception from code described by original poster. I reran the test and verified at that the trans != null && trans.Connection != null was properly set after call to BeginTransaction and all looked good and still got same exception after hitting continue. Debugging through the code again I noticed I was consistently hitting getting a timeout exception somewhere (poor wireless connection probably), and this seems to cause the connection to close. Here is the interesting bits from the logs which shows that connection seems to have closed:
NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,213 [10] ERROR NHibernate.Util.ADOExceptionReporter [(null)] - Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,237 [10] WARN NHibernate.Util.ADOExceptionReporter [(null)] - System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() at System.Data.SqlClient.TdsParserStateObject.ReadBuffer() at System.Data.SqlClient.TdsParserStateObject.ReadByte() at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlDataReader.ConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,243 [10] ERROR NHibernate.Util.ADOExceptionReporter [(null)] - Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. A first chance exception of type 'NHibernate.Exceptions.GenericADOException' occurred in NHibernate.DLL NHibernate.SQL: 2009-05-05 22:00:45,291 [10] DEBUG NHibernate.SQL [(null)] - SELECT ... NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,374 [10] WARN NHibernate.Util.ADOExceptionReporter [(null)] - System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is closed. at System.Data.SqlClient.SqlConnection.GetOpenConnection(String method) at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,381 [10] ERROR NHibernate.Util.ADOExceptionReporter [(null)] - ExecuteReader requires an open and available Connection. The connection's current state is closed. NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,408 [10] WARN NHibernate.Util.ADOExceptionReporter [(null)] - System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is closed. at System.Data.SqlClient.SqlConnection.GetOpenConnection(String method) at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) NHibernate.Util.ADOExceptionReporter: 2009-05-05 22:00:45,415 [10] ERROR NHibernate.Util.ADOExceptionReporter [(null)] - ExecuteReader requires an open and available Connection. The connection's current state is closed. A first chance exception of type 'NHibernate.ADOException' occurred in NHibernate.DLL A first chance exception of type 'Castle.MonoRail.Framework.MonoRailException' occurred in Castle.Monorail.Framework.DLL
With this in mind I wrote the following tests (both pass) to see if closing connection clears trans.Connection (it does) and if the timeout has anything to do with it. I'm thinking NH is closing the connection as it appears that Ado is not.
[Test] public void trans_connection_set_to_null_when_connection_closed() { SqlConnection connection = new SqlConnection(); connection.ConnectionString = connectionString; connection.Open(); var trans = connection.BeginTransaction(IsolationLevel.ReadUncommitted); Assert.That(trans.Connection, Is.Not.EqualTo(null));
connection.Close(); Assert.That(trans.Connection, Is.EqualTo(null));
} [Test] public void trans_connection_not_set_to_null_after_timeout() { SqlConnection connection = new SqlConnection(); connection.ConnectionString = connectionString;
connection.Open(); var trans = connection.BeginTransaction(IsolationLevel.ReadUncommitted); Assert.That(trans.Connection, Is.Not.EqualTo(null));
var cmd = connection.CreateCommand(); cmd.CommandTimeout = 1; cmd.Transaction = trans; cmd.CommandText = "WAITFOR DELAY '00:00:10'";
try { cmd.ExecuteNonQuery(); Assert.Fail("shouldn't reach here; expecting a timeout exception."); } catch (Exception ex) { Console.WriteLine(ex); }
Assert.That(trans.Connection, Is.Not.EqualTo(null)); }
|