2013/7/22 <[email protected]> > 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. >
It should probably be logged at least. Perhaps logged and ignored even, but the related code is flawed anyway. > > 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 > The session is defined to not be thread-safe. This is not a solution. > 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? > The code for dealing with TransactionScope (AdoNetDistributedTransacionFactory) is buggy. As far as I can tell, it's based on an incomplete understanding of how System.Transactions work, which is not surprising given that the documentation for that is not entirely clear. Unfortunately, not all of the related issues in NHibernate Jira have obvious solutions. Some of them may require significant behavioural changes. Personally, I haven't had a large enough block of time to devote to this yet. So far, the best advice is to ensure that you always use NHibernate's own transaction object in addition to TransactionScope, and to always commit/rollback the nhibernate transaction before disposing the TransactionScope. Does the problem occur even in this scenario? > > > 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. > > > -- --- 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.
