Hi, This would appear to be another problem in the same vein as those mentioned in https://groups.google.com/forum/#!topic/nhibernate-development/l57826ULy-Q , but is IMO far more severe since it brings down the entire appdomain without affording the application the opportunity to handle the failure.
Basically, any exception thrown in SessionImpl#AfterTransactionCompletion will cause the hosting application to crash if it occurs on the timer thread used by System.Transactions. This typically occurs due to threading issues in the session object. NullReferenceExceptions and IndexOutOfRangeExceptions seem to be the usual culprits, triggered by collections being modified in a thread-unsafe manner. Such an exception is likely to indicate corrupt state (out-of-sync caches, etc) so it's arguably correct that the appdomain goes down, but the bug lies in NHibernate and is not the application's problem. If it cannot be fixed properly it must at least be mitigated. A quick 'fix' might be to put an aggressive try..catch around all the code in the TransactionCompleted event handler and delegate to an application-specified (optional) handler, providing the option of discarding the exception instead of crashing the application. For many use cases the corruption will be restricted to the session, which is likely to have been torn down already anyway, and this will be a much better compromise than crashing. It's difficult to write a test to reproduce this problem reliably because it's thread-related. The only correct solution to the problem appears to involve making the session deal correctly with multiple threads, but the relevant state is spread across many classes and it's not obvious where the synchronisation points should be. Merely making the individual collections threadsafe doesn't solve the problem. The NHibernate documentation covers usage of the library, but I'm not sure where to find documentation about its internal structure; can someone point me to a good source of info? I need to investigate the session/transaction lifecycle more carefully, but it appears that AfterTransactionCompletion can get called twice when a distributed transaction terminates: once on the timer thread and once on the disposing thread. If it can be guaranteed to fire on the disposing thread, possibly we can simply ignore invocations from the timer thread? Alex Davidson Bluewire Technologies -- --- You received this message because you are subscribed to the Google Groups "nhibernate-development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
