I have a very straightforward dotnet core application that creates a db context
services.AddDbContext<MyContext>(options =>
{
var connectionString = settings.ConnectionString;
options
.UseMySql(
connectionString, ServerVersion.AutoDetect(connectionString),
x => x.MigrationsAssembly("My.Migrations")
);
}, ServiceLifetime.Scoped);
All requests are asynchronous. MySql connector is from Pomelo.
It serves a separate http client ( angular ) The client sometimes sends more than 20 requests simultaneously. No other clients are connected to the api. It works smoothly but from time time I see an error that the db user created too many connections (over 10).
"MySqlConnector.MySqlException (0x80004005):
User 'user-name' has exceeded the 'max_user_connections'
resource (current value: 20)\r\n at
MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs
I managed to persuade the db admin to increase the limit to 20 ( default for mysql is 10) but it did not solve the issue completely and in fact is not a good way to solve it.
Is there a way to limit the number of connections the context creates ?
Related
Hy everybody,
i need Help for the following Problem:
I have a Single-Page-Application (REACT, Webpack) with .NET Core 3.1, Devart for Oracle 9.11.980.
The first call to the Database is very slow (20 Seconds). I tested different Calls from my Single-Page-Application.
Call a Rest-API with an connection to a Database. The Response is a JSON-Object. In the DB-Table is only one record. (Duration: 22 Seconds)
Call a Rest-API without connection to a Database which is generating the same JSON-Response like the
Call in Number 1 (Duration: Milliseconds)
Call a Rest-API without connection to a Database. The Response is a string (Duration: Milliseconds).
So it seems to be the connection to the Database.
When i restart the App (e.g. F5) the Call of the Rest-API from Number 1 only needs Milliseconds.
When i Stop and Start the AppPool on IIS for that Application, the Rest-API from Number 1 needs again 22 Seconds for the first request.
It is just a simple Call to the Database:
using (Data.ma06kesch_adminModel context = new Data.ma06kesch_adminModel())
{
IQueryable<BANKOMATKARTE> query = context.BANKOMATKARTE.ToList();
}
Does anyone have a suggestion?
I am not very familiar with IIS. Maybe is it something there? I tried a few different settings but nothing was successful :-/.
Thank you very much.
Try setting "Min Pool Size=0;" in your connection string. If this doesn't help, refer to Fixing slow initial load for IIS.
In the case of large and complex EF6 model, also look at https://www.fusonic.net/developers/2014/07/09/3-steps-for-fast-entity-framework-6-1-code-first-startup-performance/.
We ar running a webapplication in Azure Web Apps using a database per customer (multiple accounts per customer). When logging in we connect the user to the correct customer database. This database is also hosted in azure (an elastic pool). It is hosted in the same region (West Europe) as the Web App.
Once the connection is pooled, request times are fast, but the first time a user log's in, the connection still needs to be created an this takes (quiet) a long time.
The connectionstring is build up using a SqlConnectionStringBuilder.
var csb = new System.Data.SqlClient.SqlConnectionStringBuilder();
csb.DataSource = "tcp:******.database.windows.net,1433";
csb.InitialCatalog = "***-***-***";
csb.UserID = "**-**";
csb.Password = "**********";
csb.MultipleActiveResultSets = true;
csb.Encrypt = true;
csb.PersistSecurityInfo = false;
csb.TrustServerCertificate = false;
csb.ConnectTimeout = 30;
_connectionString = csb.ConnectionString;
// Data Source=tcp:******.database.windows.net,1433;Initial Catalog=***-***-***;Persist Security Info=False;User ID=**-***;Password=******;MultipleActiveResultSets=True;Connect Timeout=30;Encrypt=True;TrustServerCertificate=False
Am I doing anything wrong? Or are there some settings in azure to speed up the connect process?
The above request shows the first request to the application of a customer. It therefor includes the EF Migration Seed resulting in the first 2 queries not actually going to the database itself and quite a lot of queries (not all shown here) to the database.
Well, I solved my problem eventualy. Seems i was matching wrong queries within Applications Insights. I installed Stackify and this gives just the little bit more information I needed.
Seem's Entity Framework does some things with the 'master' database. As the user in the connectionstring did not have access to the 'master' database it throws an error. Well, handling that error take's up quite some time on the app-service used and therefor returning slow. It just doesn't fail.
What EF tries to do is determine if the database exist by querying the master database wich is faster then connecting to a non existing database. If it fails because it can not connect to the master database, EF just tries to connect to the database itself. If connection to the database works, it continues normal execution like the seed method.
I am working on a project using Vapor and Mongodb.
Let's say that at a specific route
drop.get("user", String.self) { request, user in
// ... query Mongodb
}
I want to query the database and see if an input user already exists.
Is it wise to have a singleton MongoManager class that handles all the connection with the database?
drop.get("user", String.self) { request, user in
MongoManager.sharedInstance.findUser(user)
}
Do I create a bottleneck with this implementation?
No, you will not create a bottleneck unless you have a single-threaded mechanism that stands between your Vapor Handler and MongoDB.
MongoKitten (the underlying driver for Swift + MongoDB projects) manages the connection pool internally. You can blindly fire queries at MongoKitten and it'll figure out what connection to use or will create a new one if necessary.
Users of MongoKitten 3 will use a single connection per request. If multiple requests are being handled simultaneously, additional connections will be opened.
Users of MongoKitten 4 will use a single connection for 3 requests, this is configurable. The connection pool will expand by opening more connections if there are too many requests are being done.
Users of the upcoming Meow ORM (which works similar to what you're building) will use a single connection per thread. The connection pool will expand if all connections are reserved.
I have a classic spray+slick http server which is my database access layer, and I'd like to be able to have an healthcheck route to ensure my server is still able to reach my DB.
I could do it by doing a generic sql query, but I was wondering if there was a better way to just check the connection is alive and usable without actually adding load on the database (or at least the minimum possible load).
So pretty much :
val db = Database.forConfig("app.mydb")
[...]
db.???? // Do the check here
Why do you want to avoid executing a query against the database?
I think the best health check is to actually use the database as your application would (actually connecting and running a query). With that in mind, you can perform a SELECT 1 against your DB, and verify that it responds accordingly.
An asp.net application I am working on may have a couple hundred users trying to connect. We get an error that the maximum number of connections in the pool has been reached. I understand the concept of connection pools in ADO.NET although in testing I've found that a connection is left "sleeping" on the ms sql 2005 server days after the connection was made and the browser was then closed. I have tried to limit the connection lifetime in the connection string but this has no effect. Should I push the max number of connections? Have I completely misdiagnosed the real problem?
All of your database connections must either be wrapped in a try...finally:
SqlConnection myConnection = new SqlConnection(connString);
myConnection.Open();
try
{
}
finally
{
myConnection.Close();
}
Or...much better yet, create a DAL (Data Access Layer) that has the Close() call in its Dispose method and wrap all of your DB calls with a using:
using (MyQueryClass myQueryClass = new MyQueryClass())
{
// DB Stuff here...
}
A few notes: ASP.NET does rely on you to release your Connections. It will release them through GC after they've gone out of scope but you can not count on this behavior as it may take a very long time for this to kick in - much longer than you may be able to afford before your connection pool runs out. Speaking of which - ASP.NET actually pools your connections to the database as you request them (recycling old connections rather than releasing them completely and then requesting them anew from the database). This doesn't really matter as far as you are concerned: you still must call Close()!
Also, you can control the pooling by using your connection string (e.g. Min/Max pool size, etc.). See this article on MSDN for more information.