-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
System.Data.SqlClient 4.8.2 throws TransactionAbortedException (the connection has been broken) #729
Comments
Tagging subscribers to this area: @cheenamalhotra, @David-Engel |
The System version the library has been frozen and moved out of this repository in favour of Microsoft.Data.SqlClient https://github.com/dotnet/SqlClient which can be versioned separately. It contains fixes and improvements beyond those present in the framework provided versions. If possible give it a try and see if the behaviour you're seeing has already been resolved. |
Does it requires rewriting all namespaces Microsoft.*? Because we can't afford such rework in our libraries and all microservices. |
It does. You should probably consider introducing abstractions in your codebase to avoid such things causing agility limitations. |
Well, it's not that simple when you have large code base and 20 product team developers. Can I see the source code or at least changelog of what been changed in 4.8.2? |
Thanks. I can see the source now but I can't seems to see the changes in 4.8.2 |
It's part of the framework so it doesn't get it's own update schedule. You probably want to review all the pull requests which targeted files in that project. |
I couldn't find the source code in github for System.Data.SqlClient. I saw only System.Data.Common |
AFAIK System.Data.SqlClient is not open sourced but source open at https://referencesource.microsoft.com/#System.Data as mentioned above. |
It absolutely was and was part of this repository. It was removed in favour of the Microsoft version as I said earlier. To see the code you'll have to look into the history prior to it's removal. |
@Wraith2 Just curious. It was the same code for core / desktop? Where lives the System.Data.SqlClient desktop code now? |
The desktop version was distinct from the core version. This repo only contained the core version. The code was forked into Microsoft.Data.SqlClient which also contains the desktop version. The Microsoft version supercedes the System version and is versioned independently so it can be updated without a framework update. It contains performance improvements new features and bug fixes that may not be ported back to core or desktop verisons. |
Thanks. |
Tagging @saurabh500 @corivera for System.Data.SqlClient (.Net Framework) |
Could you please confirm if this issue occurs for SqlClient from .Net Framework or when referencing in a .Net Core Project? As it seems to me your application is ASP.NET Core but there are discussions for desktop version of SqlClient.. Just want to clarify to identify driver ownership. |
For applications involving .Net Core, one seemingly related change that went in S.D.S. 4.8.2 (for .Net Core) is dotnet/corefx#42937 which fixes a high security issue of data corruption. Could you also elaborate more about Cassandra driver's role in your application and how 4.8.1 version causes failures? Is it possible to run some tests without Cassandra driver in picture to really focus on SqlClient behaviour for the failing use case? |
The issue is on NETCore app running in Linux container. |
Well, Cassandra driver exception is from some background thread and seems does not impact application at all. Maybe it's just some kind of warning from the driver background processing. Since cassandra exception does not impacts my app I don't really have issue with that. It's just I thought it's strange - I only saw those kind exceptions after upgrading System.Data.SqlClient nuget package which also gets "he connection has been broken" exceptions when working with mssql. So I thought that this could somehow be related to some global app IO pooling issues caused by updated package.
We can't remove Cassandra since it's also the part of our production microservice data storage unfortunately. |
From the stack trace it seems like your application is performing "Commit" on an "Aborted/Ended" transaction. You can try to confirm this theory by either preventing "Transaction Abort" scenarios or checking `Transaction.TransactionInformation.Status" if it's "Active" before triggering operations that perform commit. Doing so should prevent the app from performing unwanted operations and hence the exceptions. If there's a different use-case in your case, please provide details with a sample code if possible. |
I'll test out your suggestion. Meanwhile I've looked into the PR and if I understood correctly you now throw a promoteException only if transaction status is aborted. So if transaction is not in aborted state and some exception occur there is a way to still get connection "doomed" and return from method without exception - is this intended? |
The condition checks for (View Change) |
Oh. I must have misread something, sorry about that. Still, with new 4.8.2 code it could be possible to get no exception from Promote and some other methods if transaction is aborted. I wonder if it's the source of my problems. You've mentioned to check if transaction is active before performing commit - how do I do that? I have code like this:
Where
And TransactionScope does not have Status field. |
Yes, that's right. Did that work for you? |
I've updated System.Data.SqlClient to 4.8.2 and changed the code to:
And I've got exceptions like before:
But still no new warnings about transaction state (there are still other old type of warnings present, so logging is working ok). There are other examples of the same exception but on different method (if it helps):
|
Could you wrap this in a minimal repro to take a closer look at the scenario? |
I would gladly, but I'm afraid I can't - the code is simple ADO.NET update but something could be with the all other stuff microservice doing (heavy CPU usage due to image resizing on Skia + cassandra and rabbitmq libraries connected to servers). |
Ok, I'll try to form a repro based on provided info. Could you also confirm if your connection is a pooled connection or pooling is disabled? And also do you also know why the transaction aborts at the first place? Are there failing commands or it's something else? Have you been able to gather it from logs and is it possible to prevent the transaction abort? |
It's default connection string so it's pooled by default (if I'm not mistaken).
Before I tested it, just to clarify - should I just add "Pooling=false" or also change min/max pool size in connection string?
I think it doesn't aborts at all. Because otherwise there should be warning about transaction in not active state before commit. |
Just changing "Pooling = false" should disable it. |
There's certainly an abort triggered somewhere, otherwise you'd never run into this issue, since the change in last release was made specifically on "Transaction Abort" callback API. You should be able to capture SQL Profiler traces for "Transaction" > "DTC Transaction" events to see which "Application" triggers "Transaction Aborted" events. You should notice something like below in SQL profiler traces:
|
We started getting the same error in .Net Framework 4.8 application under high load (lots of parallel user sessions execute database queries) after upgrade of Microsoft.Data.SqlClient from 1.1.2 to 1.1.3. using (var transactionScope = DataAccessFactory.Current.CreateTransactionScope())
{
using (var connection = DataAccessFactory.Current.CreateConnection())
{
// create and execute command ...
}
transactionScope.Complete();
} Update: Meanwhile, adding the next code in the SqlDelegatedTransaction.TransactionEnded method looks strange considering if a transaction is successfully committed: (commit 0b20c3b) // Safest approach is to doom this connection, whose transaction has been aborted externally.
// If we want to avoid dooming the connection for performance, state needs to be properly restored. (future TODO)
connection.DoomThisConnection(); |
Having the same problem here with .NET Framework 4.8 and Microsoft.Data.SqlClient 2.1.1 transaction = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions() MSDTC is used, connection pooling is used, SqlConnection is open and closed for every command at System.Transactions.TransactionStateAborted.EndCommit(InternalTransaction tx) |
Is it possible to create a repro application to mimic your scenarios where exception occurs? That would help us in understanding more about your usecase. The closing of Connection happens only on Transaction Abort event, and that's important to do because the driver does not lose reference to old transaction and continues to reattach it for next connection. If there's a server side delay to abort old transaction, server accepts that request. This in turn causes a security issue since whenever the transaction does end on the server side, the remaining queries on the new connection execute with implicit transactions. We may have to look at why an aborted transaction is being committed by your application. |
Thx for being willing to look at it. |
We have the same problem with Microsoft.Data.SqlClient under Net 5.0. With heavy parallel load the connection pooling/transaction handling seems to break down. |
@csnemes @dotWils @wolgasster @MichaelLogutov We have a potential fix for this issue in PR #1042. Thank you |
Hi, I've managed to try the patch both with the reproduction and within our application (where we originally encountered with this problem), and it works perfectly. Thanks a lot for the fix. |
Closing this issue as fixed has been merged for main(3.0), 2.1 and 1.1 servicing. |
Thx for finding a solution. |
Description
After updating System.Data.SqlClient version from old 4.6.1 to latest 4.8.2 we started to see period errors like this:
Those exceptions happening in pure ADO.NET code with TransactionScope created with ReadCommitted isolation level, TransactionScopeOption.Required, 1 minute timeout and TransactionScopeAsyncFlowOption.Enabled.
After rolling back to System.Data.SqlClient 4.8.1 those exceptions dissapeared but we saw another new type of exceptions we've never seen before from cassandra driver:
Downgrading back to 4.6.1 seems to fixed all issues.
Configuration
It happened on aspnet core 3.1 web applications and console netcore 3.1 applications with latest 3.1 images both running in container on Linux.
Regression?
It works on System.Data.SqlClient 4.6.1
Other information
This issue happening on heavy load application and only on production. I can't reproduce this issue locally.
I wish I could find source for System.Data.SqlClient library to see the diff for 4.8.2 version.
The text was updated successfully, but these errors were encountered: