AdoNetWithDistributedTransactionFactory doesn't unhook event handler which may prevent garbage collection
Description
The EnlistInDistributedTransactionIfNeeded method adds an event handler to the transactionContext.AmbientTransation.TransactionCompleted event.
There is no code to unhook this event, and when using MemProfiler to profile an app that is loading NHibernate multiple times (for integration tests) it is marked as causing instances of AdoNetWithDistributedTransactionFactory "that are directly rooted by an EventHandler" that cannot be garbage collected.
The call stack identified by .NET Memory Profiler is: NHibernate!NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.EnlistInDistributedTransactionIfNeeded( ISessionImplementor ) NHibernate!NHibernate.Impl.AbstractSessionImpl.EnlistInAmbientTransactionIfNeeded() NHibernate!NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus() NHibernate!NHibernate.Impl.SessionImpl..ctor( IDbConnection,SessionFactoryImpl,bool,long,IInterceptor,EntityMode,bool,bool,ConnectionReleaseMode ) NHibernate!NHibernate.Impl.SessionFactoryImpl.OpenSession( IDbConnection,bool,long,IInterceptor ) NHibernate!NHibernate.Impl.SessionFactoryImpl.OpenSession( IInterceptor )
Environment
None
Attachments
2
Activity
Show:
Alex Zaytsev May 1, 2017 at 3:42 AM
Closing issues resolved in 4.1.0
Alex Zaytsev May 31, 2015 at 3:12 AM
Merged to master @ 183dfe062f3633e13346214e4b9346fa9d2050cb
Oskar Berggren November 16, 2013 at 1:43 PM
I don't understand - the Transaction instance should go out of scope, and then the event handler should be eligible for collection, shouldn't it?
The EnlistInDistributedTransactionIfNeeded method adds an event handler to the transactionContext.AmbientTransation.TransactionCompleted event.
There is no code to unhook this event, and when using MemProfiler to profile an app that is loading NHibernate multiple times (for integration tests) it is marked as causing instances of AdoNetWithDistributedTransactionFactory "that are directly rooted by an EventHandler" that cannot be garbage collected.
The call stack identified by .NET Memory Profiler is:
NHibernate!NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.EnlistInDistributedTransactionIfNeeded( ISessionImplementor )
NHibernate!NHibernate.Impl.AbstractSessionImpl.EnlistInAmbientTransactionIfNeeded()
NHibernate!NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus()
NHibernate!NHibernate.Impl.SessionImpl..ctor( IDbConnection,SessionFactoryImpl,bool,long,IInterceptor,EntityMode,bool,bool,ConnectionReleaseMode )
NHibernate!NHibernate.Impl.SessionFactoryImpl.OpenSession( IDbConnection,bool,long,IInterceptor )
NHibernate!NHibernate.Impl.SessionFactoryImpl.OpenSession( IInterceptor )