I have a multithreaded C# application where each thread has it's own set of db connections. Each thread uses TransactionScope / DTC. Sometimes, I get a "The transaction has aborted" exception. It's not from a timeout since it occurs in less than 2 seconds from starting the transaction.
Here's the stacktrace:
at System.Transactions.TransactionStateAborted.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState) at System.Transactions.CommittableTransaction.Commit() at System.Transactions.TransactionScope.InternalDispose()开发者_运维知识库 at System.Transactions.TransactionScope.Dispose() at MyNamespace.CallingMethod()
It happenes very infrequently, say once in 100,000 transactions.
Environment: Windows Server 2003 .Net 2.0 Connects to SqlServer 2005
Any ideas on why this is occuring? Thanks!
Is this call stack from your inner-most InnerException? I you get this exceptions, there is usually (not always, though) an InnerException with more info.
My bet would be on a database deadlock.
You can create a memory dump, the instruction can be found here http://blogs.msdn.com/b/joncole/archive/2007/03/29/creating-a-process-memory-dump.aspx
Then you can check with windbg to reveal what's root exception caused this issue. There are lots of useful information about how to use windbg check the managed exception.
in the mean time , you can use sql profiler to monitor if any sql error happened around the time when the exception was thrown.
I think this is attributed to network instability. It is very infrequent, and hasn't reared it's ugly head in quite a few months now.
If any of you facing this issue, please be noted that I managed to find the solution and the issue.. In the app config file, a properties for the connection string missing which was the "Enlist",.
Earlier the connection string was = <add name="HIS_Test_12" connectionString="server=OXYGEN\SQL2008ENT;database=CHIS_VN_12;UID=sa;Password=1234;Max Pool Size=100;Connect Timeout=200;" providerName="System.Data.SqlClient" />
Now the updated connection string is = <add name="HIS_Test_12" connectionString="server=OXYGEN\SQL2008ENT;database=CHIS_VN_12;UID=sa;Password=1234;Max Pool Size=100;Connect Timeout=200;Enlist=False;" providerName="System.Data.SqlClient" />
As Andreas said, look at the InnerExceptions. Also hook up SQL Profiler and look for any deadlocks/terminates.
This problem can also happen if there is an inner transaction that wasn't committed. If you place a transaction scope in an using block and there is no commit, the closing bracket will rollback all transactions during dispose. This can lead to the The transaction has aborted exception with no inner exception.
using (var outerScope = new TransactionScope())
{
using (var innerScope = new TransactionScope())
{
// Some operations to be done inside a transaction
//innerScope.Complete()
} // Dispose is called here and rolls back both inner and outer scope
outerScope.Complete();
}
If an SqlException is thrown inside a transaction it will also rollback the transaction and it can get very confusing (and possibly dangerous) when the exception is handled.
精彩评论