This article is a mirror article of machine translation, please click here to jump to the original article.

View: 24272|Reply: 0

[Source] EF Core pit: DbContextPool causes database connection pool connection exhaustion

[Copy link]
Posted on 2019-11-18 14:41:59 | | |
DbContextPool is a new feature introduced in ASP.NET Core 2.1 that saves the overhead of creating a DbContext instance, but there is a small pit hidden in it.
Recently, a ASP.NET Core project ran continuously for a period of time and then an error appeared in the logs that the database connection pool reached the maximum number of connections:


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.
   at System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
At first, I thought it was some code that caused the DbContext to dispose properly, but I didn't find any clues in the code. Later, there was really nothing else to doubt, only DbContextPool, so I tried to remove DbContextPool, but the error disappeared. It was indeed caused by DbContextPool, but what makes people wonder is that DbContextPool is originally intended to save the overhead of creating DbContext instances, so how can it consume more database connections, and the load of this project is very low, how can it consume the entire connection pool?
I talked about this strange problem at the weekly meeting today, and then I suddenly thought that each DbContext instance will occupy a database connection (SqlConnection), and when DbContextPool is not enabled, as soon as the request ends, the corresponding DbContext instance will be disposed, and the database connection will be put back into the connection pool. When using DbContextPool, the DbContext will not be disposed but will be placed back into the DbContextPool after the request ends, and the DbContext will be placed back in its own pool, which means that its corresponding database connection will not be returned to the connection pool to which it belongs. Each DbContext in the DbContextPool corresponds to a database connection, and for each additional DbContext in the DbContextPool, there will be one less database connection in the database connection pool. When the two pools are of different sizes and the DbContextPool is larger than the database connection pool, the problem arises, DbContextPool freely fills the DbContext into the pool according to the size of its own pool (let's say it is 128), ignoring the size of the database connection pool (assuming it is 100), and the above error will occur when the 101st DbContext is filled.
This project uses default settings, does the default setting trigger this problem?

Looking at the DbContextPool implementation source code, the default size limit for the discovery pool is 128


Looking at SqlConnention's implementation source code, you will find that the default size limit for connection pools is 100

The default setting will trigger the problem, which is really a small pitfall.

Knowing the reason, the solution is simple, set the poolSize of the DbContextPool to less than the Max_Pool_Size of the database connection pool





Score

Number of participants1MB+1 contribute+1 Collapse reason
Zmoli775 + 1 + 1 Step on the pit and step on it +1

See all ratings





Previous:C# inherits the determination of IsAssignableFrom, IsSubclassOf
Next:MySQL Entity Framework Core exception workaround
Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com