-
Notifications
You must be signed in to change notification settings - Fork 292
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
Connections from the pool are not reused when using async methods in parallel #18
Comments
I investigated the repro code (linked above) and EF is correctly closing the connections, but it looks like they don't make it back into the pool. This seems like a SQLClient issue. |
Sql Client Isolated repro static void Main(string[] args)
{
Program p = new Program();
p.Test();
}
public void Test()
{
Parallel.For(1, count + 1, i =>
{
if (i % 1000 == 0) Debug.WriteLine(i);
DoSomething(i).ConfigureAwait(false).GetAwaiter().GetResult();
});
}
public async Task<int> DoSomething(int id)
{
using (SqlConnection connection = new SqlConnection("Server=(localdb)\\mssqllocaldb;Initial Catalog=EfCorePoolingTest;Integrated Security=true;"))
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand($"select * from MyTable where Id={id}", connection))
{
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
reader.GetValue(i);
}
}
}
}
}
return 0;
} Script for checking sleeping connections on server SELECT ConnectionStatus = CASE WHEN dec.most_recent_sql_handle = 0x0
THEN 'Unused'
ELSE 'Used'
END
, CASE WHEN des.status = 'Sleeping'
THEN 'sleeping'
ELSE 'Not Sleeping'
END
, ConnectionCount = COUNT(1)
, des.login_name
FROM sys.dm_exec_connections dec
INNER JOIN sys.dm_exec_sessions des
ON dec.session_id = des.session_id
GROUP BY CASE WHEN des.status = 'Sleeping'
THEN 'sleeping'
ELSE 'Not Sleeping'
END
, CASE WHEN dec.most_recent_sql_handle = 0x0
THEN 'Unused'
ELSE 'Used'
END
, des.login_name |
This problem is present on the Framework as well. |
I figured that the connections from the connection pool are being reused. The pool reaches its max connection limit quickly because of async opens and parallel execution. However with Connection.Close() or Dispose() the connections are not making their way back into the pool quickly enough. As a result the connection pool hits a limit of max connections. |
cc @afsanehr |
Hello @wertzui, while we are investigating on this issue, would you mind trying to set the Timeout value on the connection string to a higher number? This should for now resolve your issue with the exceptions you are receiving. I tried with |
@ajcvickers corrected, thanks! |
How does this issue going? Has it already been resolved in any version of .net core? Please, let me know if there is any progress about it |
We are also very interest in this issue status. Is there any new about it? We are experiencing this issue in our Web API wrote with ASP.NET Core 2.2, connecting in a SQL Server 2016 database, running in AWS on Linux environment. After trying the workaround suggested in another thread here, we've noticed a very small improvement, but the error continues. The workaround tried was this:
Somebody know if there are new about this error? |
I am facing same issue.. when trying to run 1000 request per second. System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached. |
++ (Team of 5) |
As recently announced in the .NET Blog, focus on new SqlClient features an improvements is moving to the new Microsoft.Data.SqlClient package. For this reason, we are moving this issue to the new repo at https://github.com/dotnet/SqlClient. We will still use https://github.com/dotnet/corefx to track issues on other providers like System.Data.Odbc and System.Data.OleDB, and general ADO.NET and .NET data access issues. |
Does everyone who encounters this problem have something similar to the line from @geleems example above: DoSomething(i).ConfigureAwait(false).GetAwaiter().GetResult(); doing a sync-to-async transition using |
As @Wraith2 explained above, never do sync over async. |
My read is that the unit tests in the original repro were attempting to mimic what would happen in a Web application that receives a large number of identical requests that execute queries to be resolved. But I don't disagree that calling GetAwaiter().GetResult() for every iteration is a root cause of thread starvation. In fact, the NormalContextAsync unit test that doesn't do this seems to reach steady state with only 4 connections. Anyway, we received a couple of reports that describe similar symptoms, and I have asked for repros. |
That is correct. The original problem came from an ASP.Net Core MVC Web Application that received a lot of requests at the same time. To reproduce the same behavior I used |
@wertzui can you confirm that in the original web app synchronous blocking was also taking place (e.g. |
I'd love to know how. It's be really nice to be able to see the code for this open source library. |
It was a regression caused in the past, the fix has been verified. |
@Wraith2 I think this change was the actual fix: |
Preview release v1.0.19221.1 has been published containing fix. Closing issue. |
Please open a new issue and provide us with below details:
|
I am experiencing this issue using EntityFrameworkCore 2.2.4 which is referencing EntityFrameworkCore.SqlServer 2.2.0 via AspNetCore.App 2.2.0. EntityFrameworkCore.SqlServer is referencing System.Data.SqlClient 4.6.1. What do I need to do in order to get the implemented fix? Also, what is the difference between Microsoft.Data.SqlClient and System.Data.SqlClient? |
Hi @elmojo EntityFrameworkCore.SqlServer 3.0.0 references Microsoft.Data.SqlClient, so upgrading EF Core to 3.0.0 should bring in the fix for this issue. Microsoft.Data.SqlClient (M.D.S) is a union of System.Data.SqlClient (S.D.S) from .NET Framework and .NET Core (CoreFx) with namespace changes and new features added. Our aim is to provide smooth transition for end users from S.D.S library. More info here. |
Visual Studio will not allow me to upgrade to Microsoft.EntityFrameworkCore 3.0.0. NU1608: Detected package version outside of dependency constraint: Microsoft.AspNetCore.App 2.2.0 requires Microsoft.EntityFrameworkCore (>= 2.2.0 && < 2.3.0) but version Microsoft.EntityFrameworkCore 3.0.0 was resolved. Microsoft.EntityFrameworkCore.SqlServer 2.2.0 is referenced by Microsoft.AspNetCore.App 2.2.0. There appear to be newer versions of Microsoft.AspNetCore.App (2.2.7 is the latest) but Visual Studio will not allow me to upgrade to them. It says they are blocked by my project. However, those newer versions do not reference Microsoft.EntityFrameworkCore 3.0.0 anyway. Upgrading to .Net Core 3.0 is not an option as we are not yet using Visual Studio 2019. Any other ideas on how to get this fix? |
EF Core 3.0 requires .NET Core 3.0 (or more precisely .NET Standard 2.1) and will not run on older versions. At this point, the only way to use EF Core with Microsoft.Data.SqlClient is to use version 3.0, so you'll have to upgrade to get the fix for this bug. |
Well isn't that just great. Upgrading to Core 3.0 is not an option as our organization does not have VS 2019 approved as of yet. Was this an introduced bug? My code worked previously (I believe on Core 2.1). Any workarounds? I've tried increasing the connection timeout and the max pool size and neither work. |
How about not using Parallel? |
Yeah, that's what I ended up doing. I rewrote the batch program to send the requests to the webapi in series as opposed to parallel. |
Hi @elmojo We're considering to back port the fix to System.Data.SqlClient for compatibility with older version of .NET Core, will update you when the fix gets merged. |
I thought .GetResult is also blocking? |
@MTrachsel yes GetResult is blocking as mentioned in the discussion above. |
@cheenamalhotra It was fixed and released for System.Data.SqlClient ? |
Hi @eglauko It was in my list of things but I was wondering if fixing for 2.2 would be needed as .NET Core 2.2 is reaching End of Life in December (a couple of weeks left). Is it possible to upgrade System.Data.SqlClient to v4.7.0 by specifying explicit package reference and continue using with your application? System.Data.SqlClient v4.7.0 contains fix for this issue. |
Hello @cheenamalhotra, thanks for your attention. |
Hi, |
Hi @Zvikawein The issue shouldn't occur in .NET Framework though. Have you tried switching to Microsoft.Data.SqlClient? If you can reproduce issue with Microsoft.Data.SqlClient in .NET Framework, please open a new ticket with repro provided. |
Hello,everyone.I am using MySql,i have some troubble.I need help. error message: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.Sometimes, error message:Unable to connect to any of the specified MySQL hosts.Sometimes,error message:Fatal error encountered during command execution. |
@cheenamalhotra , tks |
@scenerytickets this is the repo for the SQL Server .NET client, please ask MySql support for help. |
Moved from dotnet/efcore#10169 reported by @wertzui
Whem I'm using async methods (like
FirstOrDefaultAsync
) to get a result from the Database inside aParallel.For
, the connections are not correctly reused from the connection pool.The connections will rise to the configured
Max Pool Size
and after some time (around 1-2 minutes on my machine using localdb), exceptions will be thrown.Using either async methods and a normal for-loop or non-async methods an a Parallel.For-loop, the connections are properly reused and I can observe that a normal for-loop uses 1 connection and a Parallel.For-loop uses 4 connections which corresponds to MaxDegreeOfParallelism.
Steps to reproduce
Further technical details
EF Core version: 2.0.0 (also tested with 1.1.3)
Database Provider: Microsoft.EntityFrameworkCore.SqlServer/localdb
Operating system: Windows 10 FCU
IDE: Visual Studio 2017 15.4.1
The text was updated successfully, but these errors were encountered: