Reputation: 5666
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
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.
Upvotes: 1
Views: 988
Reputation: 3829
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.
Upvotes: 2
Reputation: 138915
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.
Upvotes: 1
Reputation: 29332
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.
Upvotes: 0