I have found TS to be finicky in an http enviornment. I believe it's
related to threads and the http context. I removed the TS in favor or
NH transactions and things worked as expected.

IIRC the session needs to open within the scope of TS otherwise the
connection is not registered with the TS. The TS doesn't dispose of
the session, but if it's opened within the TS, it should be disposed
of before existing the TS.
using(var scope = new TransactionScope())
using(var session = factory.OpenSession())
{
   do work
   scope.Complete();
}

I have read about a memory leak in 2.1.2 concerning TS. if the scope
is disposed without committing the transaction doesn't rollback and
you have a leaked resource. the work around is

using(var scope = new TransactionScope())
using(var session = factory.OpenSession())
using(var tx = session.BeginTransaction())
{
   try
   {
       do work
       scope.Complete();
   }
   catch
   {
       tx.Rollback();
       throw;
   }
}

On Oct 5, 10:13 am, Mark Wilkins <[email protected]> wrote:
> I've read through many of the posts in this group on using
> TransactionScope, and have also been around the web once or twice.
> However, I still can't find the answer I'm looking for.
>
> I'm using NH 2.1.2 in an ASP.NET 2.0 web application, going against a
> SQLServer 2005 DB. I'm using the session-per-request pattern, and am
> using an HTTP Module to create/close my sessions.
>
> NH is working well for me throughout the application...except for one
> particular page. In this page, I have to interact with the DB through
> my shiny new NH code, and existing ADO Command object/Typed Dataset
> code.  As a result, I am using TransactionScope.
>
> I'll start with some of the code:
>
> Here's my HTTP module (yes, it's VB.NET. bleh):
>
> Public Sub Init(ByVal context As System.Web.HttpApplication) Implements
>           System.Web.IHttpModule.Init
>   AddHandler context.BeginRequest, AddressOf Application_BeginRequest
>   AddHandler context.EndRequest, AddressOf Application_EndRequest
> End Sub
>
> Private Sub Application_BeginRequest(ByVal sender As Object, ByVal e
> As EventArgs)
>   Dim session As ISession = NHibernateHelper.OpenSession()
>   CurrentSessionContext.Bind(session)
> End Sub
>
> Private Sub Application_EndRequest(ByVal sender As Object, ByVal e As 
> EventArgs)
>   Dim session As ISession =
>     CurrentSessionContext.Unbind(NHibernateHelper.SessionFactory)
>
>   If session IsNot Nothing Then
>     If session.Transaction IsNot Nothing AndAlso
> session.Transaction.IsActive Then
>       session.Transaction.Rollback()
>     End If
>     session.Close()
>   End If
> End Sub
>
> Here's the code for when the user clicks 'Save':
>
> Using scope As New TransactionScope()
>   Dim nhsession As ISession = NHibernateHelper.GetCurrentSession()
>   Using tx As ITransaction = nhsession.BeginTransaction()
>     ' update the objects from user input
>     ' using both NH objects and the legacy ADO Command/Typed Datasets
>     tx.Commit()
>   End Using
>   scope.Complete()
> End Using
>
> In addition, and separate from the "Save" event, the page must update
> a table that keeps track of the user's progress through a series of
> steps. So, at some other point in the execution of the page, but after
> the above code has executed, the following will happen:
>
> Dim nhsession As ISession = NHibernateHelper.GetCurrentSession()
> Using tx As ITransaction = nhsession.BeginTransaction()
>   ' ...
>   ' set properties on NH object, myObject
>   ' ...
>   myObjectService.Save(myObject)
>   tx.Commit()
> End Using
>
> Oh, the NHibernateHelper was taken from the NHIA book:
>
> Public Class NHibernateHelper
>   Public Shared ReadOnly SessionFactory As ISessionFactory
>
>   Shared Sub New()
>     Try
>       Dim cfg As New Configuration()
>       SessionFactory = cfg.Configure().BuildSessionFactory()
>     Catch ex As Exception
>       Throw New Exception("NHibernate initialization failed", ex)
>     End Try
>   End Sub
>
>   Public Shared Function OpenSession() As ISession
>     Return SessionFactory.OpenSession()
>   End Function
>
>   Public Shared Function GetCurrentSession() As ISession
>     Return SessionFactory.GetCurrentSession()
>   End Function
> End Class
>
> Finally...the problem seems to be...
>
> SOMETIMES, when the execution gets to the second step of saving the
> user's progress, this line:
> Using tx As ITransaction = nhsession.BeginTransaction()
>
> results in tx being Nothing (null).
>
> I'm wondering...does calling Complete on the TransactionScope in the
> first step cause the NH session to be closed? Perhaps this is why it
> can't begin a transaction?
>
> Should I change the second step so that it creates its own session?
>
> Sorry if I've rambled. I'd be happy to clarify anything, if it's confusing.
>
> Thanks,
>
> Mark

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to