In your repro I think the two sessions (therefore two DB connections) in the same tx scope causes a promotion to a distributed transaction which follows the asynchronous two-phase commit mechanism. The commit/rollback decision is communicated back via a separate thread.
Just added my comment to the related NH-3023: https://nhibernate.jira.com/browse/NH-3023?focusedCommentId=29652&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-29652 On Thursday, May 2, 2013 6:00:53 AM UTC-3, Johannes Gustafsson wrote: > > Yes, it seems to only show up when using multiple NH sessions. > > I managed to track it a bit further. See here: > http://pastebin.com/dKyu6YN9 > > In the code above I use 2 NH transactions. When I get an exception from > NH, I first try to rollback the first transaction. This succeeds. It seems > though that NH also rolls back the second TX but it doesn't update the > transaction object immediately (probably because it is done in a background > thread). If, howerver, I insert a thread.sleep() after tx #1 rollback, then > the IsActive property on Tx #2 will return false and the code will work as > expected. > > So the best workaround should be to simply remove the rollback I suppose. > > > 2013/5/1 Ramon Smits <[email protected] <javascript:>> > >> >> Well, AFAIK the NH transaction is automatically rolled back in the >> dispose so there is no need to explicitly call Rollback on the nhibernate >> transaction but it should not result in e exceptions. >> >> >> Just looking at the NSB code at >> https://github.com/NServiceBus/NServiceBus/blob/master/src/nhibernate/UnitOfWork/NServiceBus.UnitOfWork.NHibernate/UnitOfWorkManager.cs >> >> >> var session = CurrentSessionContext.Unbind(SessionFactory); >> >> using (session) >> using (session.Transaction) >> { >> if (!session.Transaction.IsActive) >> return; >> >> if (ex != null) >> session.Transaction.Rollback(); >> else >> session.Transaction.Commit(); >> } >> >> >> They perform an explicit rollback as you mentioned. >> >> Are you maybe also using NHibernate within you own message handlers or >> saga's? >> >> >> >> >> >> -- Ramon >> >> >> On Tue, Apr 30, 2013 at 2:34 PM, Johannes Gustafsson >> <[email protected]<javascript:> >> > wrote: >> >>> I have discovered that if NH throws certain exceptions and you after >>> that explicitly rolls back the NH transaction (like NSB does), then it will >>> consistently corrupt the connection pool. Removing the explicit rollback >>> makes the problem go away, at least in this specific scenario. >>> >>> Example >>> >>> using (create TxScope) >>> using (open session) >>> using (begin NH.Trans) >>> >>> try { >>> session.QueryOver()...SingleOrDefault() // results return 2 rows which >>> makes NH throw >>> } >>> catch (Exception) { >>> nhtx.Rollback(); // Throws with message: ROLLBACK without >>> corresponding BEGIN >>> // Connection pool is now corrupt >>> } >>> >>> >>> >>> 2013/4/30 Yngve Nilsen <[email protected] <javascript:>> >>> >>>> Exactly the same problem here when running NHibernate in NServiceBus >>>> hosted services. In our case it doesn't have to be a deadlock, just a >>>> general failure within the transaction. It seems to be related to the fact >>>> that the SQL ConnectionPool and DTC have some issues with >>>> multithreading... >>>> Would be awesome to see a fix for this in NHibernate, since I don't think >>>> the underlying MSDTC or SqlConnectionPool is going to be changed anytime >>>> soon. >>>> >>>> >>>> On Friday, October 19, 2012 2:21:39 PM UTC+2, Roy Jacobs wrote: >>>>> >>>>> Hi all, >>>>> >>>>> I see quite a few bugs on JIRA relating to the same topic: >>>>> https://nhibernate.jira.com/**secure/IssueNavigator.jspa?** >>>>> reset=true&jqlQuery=labels+%**3D+TransactionScope<https://nhibernate.jira.com/secure/IssueNavigator.jspa?reset=true&jqlQuery=labels+%3D+TransactionScope> >>>>> >>>>> They're all about the fact that SQL errors cause a session's >>>>> SqlConnection to be closed from a different thread than the thread that >>>>> opened it (through the AdoNetDistributedTransacionFac**tory). We've >>>>> been running into this issue for quite some time now as well. We store >>>>> NServiceBus saga's using NHibernate and occasionally we may get a >>>>> deadlock. >>>>> Normally this would not be a huge problem (just retry the message), but >>>>> once this deadlock occurs, we get, for a minute or 2, a log full of >>>>> errors >>>>> like "New request is not allowed to start because it should come with >>>>> valid >>>>> transaction descriptor" and "Distributed transaction completed. Either >>>>> enlist this session in a new transaction or the NULL transaction.". >>>>> >>>>> Now, this is something we'd like to have fixed, or fix ourselves. Is >>>>> anyone actively looking at this, right now? Or willing to share some >>>>> suggestions/findings? >>>>> >>>>> Roy >>>>> >>>> -- >>>> >>>> --- >>>> 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]<javascript:> >>>> . >>>> 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]<javascript:> >>> . >>> 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]<javascript:> >> . >> 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.
