Threading & Transaction Errors With Multi-Database

69 views
Skip to first unread message

Tim Scott

unread,
Nov 2, 2010, 3:57:48 PM11/2/10
to ncommon
I upgraded to NCommon 1.1 in order to use the multi-database feature.
It got it working fine on my dev box (XP), but it breaks down in the
QA environment (Server 2003).

When I first deployed to QA each request that spanned multiple
databases was failing. Problem #1 was that had to enable MSDTC on
both the the DB box and the web server. But database-spanning
requests continue to fail intermittently. Usually the first error is:

ERROR: System.InvalidOperationException: A TransactionScope must be
disposed on the same thread that it was created.
at System.Transactions.TransactionScope.Dispose()
at NCommon.Data.Impl.UnitOfWorkTransaction.Dispose(Boolean
disposing) in F:\SANDBOX\NCommon\NCommon\src\Data\Impl
\UnitOfWorkTransaction.cs:line 168
at NCommon.Data.Impl.UnitOfWorkTransaction.Dispose() in F:\SANDBOX
\NCommon\NCommon\src\Data\Impl\UnitOfWorkTransaction.cs:line 152
at
NCommon.Data.Impl.UnitOfWorkTransaction.OnScopeCommitting(IUnitOfWorkScope
scope) in F:\SANDBOX\NCommon\NCommon\src\Data\Impl
\UnitOfWorkTransaction.cs:line 124
at NCommon.Data.UnitOfWorkScope.OnCommit() in F:\SANDBOX\NCommon
\NCommon\src\Data\UnitOfWorkScope.cs:line 143
at NCommon.Data.UnitOfWorkScope.Commit() in F:\SANDBOX\NCommon
\NCommon\src\Data\UnitOfWorkScope.cs:line 124
at UnitedRoad.Logistics.Web.UI.Global.Application_EndRequest(Object
sender, EventArgs e) in c:\Builds\Logistics\Checkout\Source\Application
\Logistics.Web.UI\Global.asax.cs:line 58

After that I get a sprinkling of:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Transaction'.
...followed by:
System.InvalidOperationException: The current TransactionScope is
already complete.
...and sometimes:
System.Transactions.TransactionAbortedException: The transaction has
aborted. ---> System.TimeoutException: Transaction Timeout

The app uses a UoW per request pattern. Here is the code from my
HttpApplication (simplified):

private IUnitOfWorkScope unitOfWorkScope;

protected void Application_BeginRequest(object sender, EventArgs e)
{
unitOfWorkScope = new UnitOfWorkScope();
}

protected void Application_EndRequest(object sender, EventArgs e)
{
try
{
unitOfWorkScope.Commit();
}
finally
{
unitOfWorkScope.Dispose();
}
}

I also tried this (again, simplified):

protected void Application_BeginRequest(object sender, EventArgs e)
{
new UnitOfWorkScope();
}

protected void Application_EndRequest(object sender, EventArgs e)
{
try
{
UnitOfWorkManager.CurrentUnitOfWork.Flush();
}
finally
{
UnitOfWorkManager.CurrentUnitOfWork.Flush();
}
}

What am I doing wrong? The samples scope the UoW in controller
methods. I surely do not want to do that. I've got a months worth
of work that depends on slaying this problem. Any ideas are much
appreciated.

Ritesh Rao

unread,
Nov 2, 2010, 4:55:58 PM11/2/10
to nco...@googlegroups.com
Tim,

Would you happen to have some sample code that would repro this issue? What data provider are you using? NH/EF/L2S ? 




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


Tim Scott

unread,
Nov 2, 2010, 5:06:21 PM11/2/10
to nco...@googlegroups.com
I am using NH.  

No, no sample.  It would take quite an effort to develop a sample that has the relevant traits.  However, if it comes to that, I would have to do it.  I was hoping you would say, “Aha, you’re managing UoW scope wrong,” and it would be an easy fix.

Currently I am in the process of trying the fixes suggested in issues #16 and #17, which supposedly fix threading issues.  Maybe you have an opinion about that?
To unsubscribe from this group, send email to ncommon+u...@googlegroups.com <mailto:ncommon%2Bunsu...@googlegroups.com> .

Tim Scott

unread,
Nov 2, 2010, 11:59:59 PM11/2/10
to nco...@googlegroups.com
Here’s a clue:

2010-11-02 23:33:45,558 [web1devursdca] [7] [] DEBUG: UnitOfWorkScope created.
UoW:10511147  Request:11323545
2010-11-02 23:33:45,558 [web1devursdca] [5] [tscott] DEBUG: Committing UnitOfWorkScope.
UoW:10511147  Request:11323545
2010-11-02 23:33:45,558 [web1devursdca] [5] [tscott] ERROR: System.InvalidOperationException: A TransactionScope must be disposed on the same thread that it was created.

at System.Transactions.TransactionScope.Dispose()
at NCommon.Data.Impl.UnitOfWorkTransaction.Dispose(Boolean disposing) in F:\SANDBOX\NCommon\NCommon\src\Data\Impl\UnitOfWorkTransaction.cs:line 168
   at NCommon.Data.Impl.UnitOfWorkTransaction.OnScopeCommitting(IUnitOfWorkScope scope) in F:\SANDBOX\NCommon\NCommon\src\Data\Impl\UnitOfWorkTransaction.cs:line 124

   at NCommon.Data.UnitOfWorkScope.OnCommit() in F:\SANDBOX\NCommon\NCommon\src\Data\UnitOfWorkScope.cs:line 143
   at NCommon.Data.UnitOfWorkScope.Commit() in F:\SANDBOX\NCommon\NCommon\src\Data\UnitOfWorkScope.cs:line 124
   at UnitedRoad.Logistics.Web.UI.Global.Application_EndRequest(Object sender, EventArgs e) in c:\Builds\Logistics\Checkout\Source\Application\Logistics.Web.UI\Global.asax.cs:line 67

The hash codes of the unit of work scope and the HTTP request prove that we have the same UoW scope instance at the beginning and end of the request.  But the request begins on thread 7 and ends on thread 5.  TransactionScope.Dispose() does not like that.  From what I’ve read, a request normally stays on a single thread.  Is there anything about multiple databases in NCommon that could cause the request to “jump threads?”

What’s strange is that I don’t get this on my local box.  Maybe because it’s XP.  Also, we’ve used Ncommon 1.0 (single database) for a good while now with no issues like this.

Thanks again for any ideas or help.



On 11/2/10 3:55 PM, "Ritesh Rao" <rao.r...@gmail.com> wrote:

To unsubscribe from this group, send email to ncommon+u...@googlegroups.com <mailto:ncommon%2Bunsu...@googlegroups.com> .

Tim Scott

unread,
Nov 3, 2010, 12:50:17 PM11/3/10
to ncommon
All errors go away if I make the unitOfWorkScope field ThreadStatic.
But I am nervous about this. I have been reading up, but I am not
sure whether it is possible for two requests to simultaneously share a
thread. Or if not, do I create a performance problem. The real
problem is that issues might only show up under load. [shudder]

Tim Scott

unread,
Nov 3, 2010, 1:55:13 PM11/3/10
to ncommon
I take it back. TheadStatic does not solve anything.
Reply all
Reply to author
Forward
0 new messages