Cannot access a disposed object. Object name: 'AdoTransaction'.

6,475 views
Skip to first unread message

Amzath

unread,
Aug 31, 2010, 6:36:15 PM8/31/10
to nhusers
Getting an error when commiting the transaction. I am opening and
closing the session properly. But I dont know why this error occurs?
Can any one helps me?

Code:


using (var tx = new
TransactionScope(TransactionScopeOption.Suppress))
using (var session =
_sessionManager.OpenSession(DatabaseAli))
{
using (var tran =
session.BeginTransaction())
{


var Customer =
_repository.Get(new
CustomerByCustomerId(CustomerUpdate.CustomerIdentifier));



UpdateCustomerInfo(Customer, CustomerUpdate);



UpdateCustomerAccountLimit(Customer, CustomerUpdate);



UpdateCustomerMethods(Customer, CustomerUpdate);



_repository.Store(Customer);


tran.Commit();
}
tx.Complete();
}


Error:


2010-08-31 16:01:41,687 [Worker.5] ERROR
MyTest.ConsumerApp.Services.Handlers.CustomerUpdater [(null)] - End:
HandlingMessage: Failed handling CustomerUpdate message from
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'AdoTransaction'.
at NHibernate.Transaction.AdoTransaction.CheckNotDisposed()
at NHibernate.Transaction.AdoTransaction.Commit()
at
MyTest.ConsumerApp.Services.Handlers.CustomerUpdater.Handle(CustomerUpdate
CustomerUpdate) in C:\MyTest\trunk\ConsumerApp\Services\Handlers
\CustomerUpdater.cs:line 113


Fabio Maulo

unread,
Aug 31, 2010, 7:09:02 PM8/31/10
to nhu...@googlegroups.com
Put  tx.Complete() in the 'using' of the TxScope not in the 'using' of the session.



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




--
Fabio Maulo

Amzath

unread,
Sep 1, 2010, 11:43:47 AM9/1/10
to nhusers
That did not help. Any other way to figure out why is that occuring?
> > nhusers+u...@googlegroups.com<nhusers%2Bunsu...@googlegroups.com­>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/nhusers?hl=en.
>
> --
> Fabio Maulo- Hide quoted text -
>
> - Show quoted text -

Amzath

unread,
Sep 1, 2010, 1:22:55 PM9/1/10
to nhusers
As handler does not use MSDTC, I have removed transaction scope from
the code. Now code looks like this but getting same exception. Please
help me on this I have this issue in for last 10 days and could not
figure out why.
> > - Show quoted text -- Hide quoted text -

Fabio Maulo

unread,
Sep 1, 2010, 1:26:48 PM9/1/10
to nhu...@googlegroups.com
You are closing the session in some other place.
You will easy found it if you will try to recreate the situation in a pure-NH-100% test without all your wrappers (_sessionManager, _repository).

To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.




--
Fabio Maulo

Amzath

unread,
Sep 2, 2010, 3:20:36 PM9/2/10
to nhusers
You are right Fabio. I did remove NHibernate facility and IRepository
dependency, configured ISessionFactroy, instead of IRepository just
build query directrly in the code. Did not get any error. There is
problem in IRepository when used with the Castle NHibernate Facility
Session manager. But it does not error out consistently and but in
random when used with WCF and NService bus together. Thank you for
guideness.

But that arises another question, how it closes the session. May not
be right to ask in this forum? But any help would be appreciated.

This is how my IReposity Get implementation looks like

[Transaction(TransactionMode.Requires)]
public virtual T Get<T>(IQuery<T> query)
{
using (var session = _sessionManager.OpenSession(DbAlias))
{
return
query.BuildQuery(session).List<T>().FirstOrDefault();
> > <nhusers%2Bunsu...@googlegroups.com<nhusers%252Bunsubscribe@googlegroup­s.com>

Jason Meckley

unread,
Sep 2, 2010, 4:25:26 PM9/2/10
to nhusers
I would get the problem is lazy loading with a disposed session. you
dispose the session right after you return the value, if you access
any referenced entities lazy loading would fail because the session is
closed. typically using the session like this is a bad practice. you
cannot take advantage of the NH features because the scope of the
session is so narrow.
var(session = factory.OpenSession())
{
return session.Get<Entity>(id);
}

in terms of a service bus (NServiceBus, Rhino, Mass Transit) the
tyipcal usage would look like this:
message arrives > open session, begin transaction
process message > within handler/consumer & various components inject
the current session (created when the message arrived)
message completes > commit (rollback on error) dispose of transaction
and session.

this means the handlers and services are transient, not singletons. I
use the CurrentSessionContext feature built into NH to manage this for
me. No need for Castle.NhibernateFacility at all.

Rhino service bus has interface IMessageModule. NSB and MT have the
same component, with a different name. it would look like this
class Uow : IMessageModule
{
public class Uow(ISessionFactory factory)
{
this.factory = factory
}

public void Init(ITransport transport)
{
transport.MesasgeArrived += OpenSession;
transport.MesasgeCompleted += CompleteSession;
}

public void Stop(ITransport transport)
{
transport.MesasgeArrived -= OpenSession;
transport.MesasgeCompleted -= CompleteSession;
}

private bool OpenSession(MessageInformation info)
{
if(CurrentSessionContext.HasBind(factory)) return false;

var session = factory.OpenSession();
session.BeginTransaction();

CurrentSessionContext.Bind(session)

return false;
}

private void CompleteSession(MessageInformation info, Exception e)
{
if(CurrentSessionContext.HasBind(factory) == false) return;

using(var session = CurrentSessionContext.Unbind(factory))
using(var tx = session.Transaction)
{
if(e == null)
tx.Commit();
else
tx.Rollback();
}
}
}

you can then reference the current session using
factory.GetCurrentSession();
in the config file add
<property name="current_session_context">thread</property>

Amzath

unread,
Sep 2, 2010, 6:26:19 PM9/2/10
to nhusers
Repository method does not dispose the session as it tied to
transaction.Thats how NHibernate facility works. We implemented that
method based on the ISessionManager in Castle facility see this link
http://www.castleproject.org/container/facilities/trunk/nhibernate/usingit.html.
It works well when we use with the WCF service. But turned into an
error in NServicebus case. I think as you suggest, I have to implement
IMessage module to manage the session for nService bus. In WCF, we are
managing session using InstanceContext see this one
http://www.candland.net/blog/2009/10/27/NHibernateSessionPerRequestUsingCastlesWcfFacility.aspx.
But we are not doing anything in case of NService bus. Thats why I
said I have to implement the IMessage module.

My WCF service already configuring session factroy specific to wcf per
request basis. As my handler is in wcf service, now my question is
where to configure the ISessionFactory for nservice bus? In
Application_Start event of wcf service? or somewhere else like in this
code http://github.com/andreasohlund/Blog/blob/master/NHibernateSample/NHibernateSample.PersisterService/EndpointConfig.cs

I have read this article it is related to my problem
http://andreasohlund.blogspot.com/2010/02/nhibernate-session-management-in.html.

Hope I put lot stuff in here. But I am confused with all these
together. Any help would be appreciated.

Jason Meckley

unread,
Sep 3, 2010, 8:49:09 AM9/3/10
to nhusers
when I first started using NH I used the NH facility for castle, but I
found that it wasn't needed, managing the session and transactions was
simpler than that.
I build the session factory when I configure the container.
Componet.For<ISession>.Instance(new
Configuration().Configure().BuildSessionFactory());

something else to consider... if you are receiving messages on the bus
in a web environment, you need to use a hybrid session context (or
implement one yourself). for the web the session can be stored in the
Request.Items collection. this doesn't exist if you receive a message
on the bus in a web app. for that you need to store the session on the
current thread.
There are issues storing the session on the thread in a web
environment because multiple requests can be handled by the same
thread (or something to that effect).

In this instance you need to either not use NH within the context of
the bus, or create a hybrid session context where it will store the
session in Request.Item if the current http context is not null,
otherwise store the session on a thread static variable.

On Sep 2, 6:26 pm, Amzath <thayumana...@gmail.com> wrote:
> Repository method does not dispose the session as it tied to
> transaction.Thats how NHibernate facility works. We implemented that
> method based on the ISessionManager in Castle facility see this linkhttp://www.castleproject.org/container/facilities/trunk/nhibernate/us....
> It works well when we use with the WCF service. But turned into an
> error in NServicebus case. I think as you suggest, I have to implement
> IMessage module to manage the session for nService bus. In WCF, we are
> managing session using InstanceContext see this onehttp://www.candland.net/blog/2009/10/27/NHibernateSessionPerRequestUs....
> But we are not doing anything in case of NService bus. Thats why I
> said I have to implement the IMessage module.
>
> My WCF service already configuring session factroy specific to wcf per
> request basis. As my handler is in wcf service, now my question is
> where to configure the ISessionFactory for nservice bus? In
> Application_Start event of wcf service? or somewhere else like in this
> codehttp://github.com/andreasohlund/Blog/blob/master/NHibernateSample/NHi...
>
> I have read this article it is related to my problemhttp://andreasohlund.blogspot.com/2010/02/nhibernate-session-manageme....
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages