1

I'm occasionaly getting this exception on our production server:

System.ArgumentNullException: Value cannot be null.
   at System.Threading.Monitor.Enter(Object obj)
   at System.Data.ProviderBase.DbConnectionPool.TransactedConnectionPool.TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject)
   at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment)
   at System.Transactions.TransactionStateDelegatedCommitting.EnterState(InternalTransaction tx)
   at System.Transactions.CommittableTransaction.Commit()
   at System.Transactions.TransactionScope.InternalDispose()
   at System.Transactions.TransactionScope.Dispose()
   //... continues here with references to my DAL code

What is the reason for this exception to happen?

I have already did some research on this but with no conrete success yet. I also read this questions here:

And now I know that if I could avoid escalating my transactions to DTC I would get rid of this problem. But what if I could not? I have multiple databases to update or read from in one transaction so I have to use DTC. I'm getting this error ocassionaly on actions that usually works well.

Technical background

  • It is ASP MVC2 and LINQ2SQL application on .NET 3.5
  • We have three virtuals with load balanacing based on IP address, each having IIS7
  • Single virutal with SQL server 2008 - it is shared by web servers

I should point out that I was not able to reproduce this exception on my development machine (development server + SQL express 2008) and on our testing machine (virtual with single IIS7 and SQL server 2008 together) either.

I'm suspecting our production servers configuration that there is some threading/processing issue (like two processes are trying to use the same connection).

UPDATE

I have found another link. It is stating that ado.net connection dispose bug is probably back. But it is a pity there is no resolution in the end and I have found nobody else describing similar issue.

Community
  • 1
  • 1
mipe34
  • 5,596
  • 3
  • 26
  • 38

3 Answers3

2

According to http://support.microsoft.com/kb/960754, there is an issue with 2.50727.4016 version of System.Data.dll.

If your server has this older version, I would try to get the updated one from Microsoft.

Jack Bolding
  • 3,801
  • 3
  • 39
  • 44
  • We have asked Microsoft for hotfix and deployed it on our production server. And now it seems that problem has gone. Thanks man! – mipe34 Nov 23 '12 at 15:23
1

It looks like a bug, as it's .NET internal code, nothing do do with your own code.

If you take a look with reflector (or any other IL tool) on the internal TransactedConnectionPool.TransactionEnded method, you will see its implementation has changed between .NET 3 and .NET 4... I suppose it was not thread-safe back then. You could try to report it to Microsoft Connect.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • Thanks. I have just posted it there. But they have only forms for .NET 4.0 and 4.5 so I don't believe they will bother with such an old thing. It also came to my mind that it could be bug, but it is very strange to me that nobody (except the one in my update) has encouter this problem yet. – mipe34 Nov 12 '12 at 19:59
0

According to the doco MSDN System.Transactions.TransactionScope the method is synchronous and therefore it's using the monitor. The doco doesn't say that the method is threadsafe, so I think it's likely that you are somehow calling dispose on the same Transaction scope object from more than one thread. You can use a static property of the transactionscope object System.Transactions.Transaction.Current to find out which transaction you are referring to. Perhaps a log message prior to disposing your transaction scope might expose where this is occurring...

If it's not a threading issue then odds on you've found a corner case that trips a bug in .Net. I've found the behaviour of MSDTC when things go wrong to be unpleasant at best.

Spence
  • 28,526
  • 15
  • 68
  • 103
  • Thanks for reply. I'm not creating any threads on my own. It is quite simple CRUD app based on ASP MVC2. How could Information about Transaction help me (I see there is distributed and local transaction id, creation time and Status)? I know exactly on which part of my code it occurs, but I don't know the conditions why. – mipe34 Nov 12 '12 at 14:33
  • You could have two different transaction scopes that use the same transaction. if both scopes try to dispose the transaction then you'll hit this error. As you said you are using ASP.Net then you are of course using threads as every page display is served up potentially on different threads. Do you have a static or shared library with some state that you use to cache the sql queries/transactions? – Spence Nov 14 '12 at 05:12