In our enviroment we use SQLServer Always on cluster with two servers.
One of them is for write, second for reading. In application services SqlConnection opens and closes every second for short query execution. But after switching or turning off one of the servers in Always On cluster I began get an exceptions from my application services.
This tells that it can not insert any data in read only database. I suppose that main reason for this is connection pool inside SqlConnection implementation.
So the question is how to reset that connection pool manually. Or if there another kind of problem - let me know what do you think about this behavior.
You need to set MultiSubnetFailover = True in connection string and implement retry logic:
If a SqlClient application is connected to an AlwaysOn database that
fails over, the original connection is broken and the application must
open a new connection to continue work after the failover.
SqlClient Support for High Availability, Disaster Recovery
Also:
Setting MultiSubnetFailover to true isn't required with .NET Framework
4.6.1 or later versions.
Related
I am running a simple .NET Core 3.1 web application on localhost. The web application is running in a Docker Linux container (my host OS is Windows 10). The SQLite database used by the web application is connected using EF Core, is almost empty and very small at 60Kb, each table having 20 records or less, and is stored on the host and mounted for the container using following command:
--mount type=bind,source='SomeDummyHostPath',target=/mnt/hostFolder
The problem is that every query executed on DBContext runs very slow (~2s for reading 2 rows). When I run the application outside of the Docker container, everything runs smoothly (meaning that the same query is executed in ~1ms).
What is strange is, after invoking dbContext.Database.OpenConnectionAsync() before every call to EF's DBSets, every query in the Docker container runs quickly (a few milliseconds).
Why is the performance so bad in this scenario? Is there any way to improve it without the explicit call to OpenConnectionAsync before every query?
EF Core 3.x included one breaking change that affects this use-case, the connection is closed earlier:
Database connection is now closed if not used anymore before the
TransactionScope has been completed
Mitigations:
If the connection needs to remain open explicit call to
OpenConnection() will ensure that EF Core doesn't close it
prematurely
The sqlite provider is still not using connection pooling: 13837;
With the new releases of EntityFrameworkCore.Sqlite (>3.0), there are some new optimizations regarding transactionality, and new .WAL file is created when the .db file is open; This, combined with lack of connection pooling results in creating and removing the .WAL file with every request; And docker volume/file mapping to windows file system gets to be very time consuming.
There is not much more to explain than what Lucian has already done in the accepted answer. Anyway, I will restate to contextualize the link.
The problem is all about EF Core closing and reopening the connection every statement.
One way to work around this is providing the connection (already open) by yourself. EF does not auto close connections that were already open.
As he also stated, at the time of this answer, the connection provider for SQLite still don't use a connection pool.
The best way to achieve the maximum performance with EF Core and SQLite is to provide a connection pool. The goal of the pool is maintaining some connections always open, because the problem itself is the overhead of opening new connections.
Finally, the link is a comment that I've made in the EF Core GitHub issue tracker containing a complete example of how to do that in a simple way.
https://github.com/dotnet/efcore/issues/13837#issuecomment-821717602
I want to check availability of database connection so that I could put my application in specific modes; online mode and offline mode.
In order to do so, I try to open an OleDB connection (the database is Oracle) and if it is successful, the application shall run in online mode. However, if the database is down, opening the connection shall only be closed after specific period of time due to timeout.
Is there specific way of doing this without having to wait for the timeout? Or maybe, specify the timeout interval?
There is no other way then connecting to the database service.
However you could Mmdify the ConnectionTimeout property of your Connection instance before opening it to tweak the amount of time you want to wait.
On the other hand you could always start with the offline mode, do the connection check async and change the application behavior when the check was succeeded.
I have a C# application that uses a localhost DB (MySQL).
Now, when I create the executable I´m assuming that the receptor computer MUST have the exact DB with the the same name and tables, also, must have running WAMP or XAMPP.
If one of this conditions is not accomplished the program will crash horribly, with the errors of Windows/C#.
I could put exceptions for every case, but I´m fearful that I would hide other errors putting exceptions for everything!
With production software, how do you manage this? With exceptions? Writing a manual for the user? etc?
During bootstrapping, I recommend check to see if a DB Connection can be created (in my case, SQL Server), given the database connection string defined in an app.config. Initially, you should do some version checking on the database. If the database can't be found, attempt to create it. if i'ts out of date, attempt to upgrade it. If this process fails, then your database engine instance isn't installed or is unresponsive. For my application case, I exit the program, as there's nothing else to do if the DB can't be accessed.
Once past this point, I generally assume that the DB connection is active.
I have a .Net service that has a list of strings containing ODBC connections and I use these in a loop to check multiple databases for tasks to process (eg. polling).
However if i change where an ODBC connection points to..by changing its default database for some reason, even though i'm only storing the string name of the ODBC connection it doesn't pick up the change until i restart the application.
Is .net somehow caching all the odbc connections on startup??
How can i work around this?
Cheers.
Check if the Connection Pooling is enabled for the ODBC driver you are using at the ODBC Data Sources control panel window (this is not a .NET issue). A successful connection will stay in the pool without refreshing its new connection properties.
If your settings are stored in the app.config, here is a question that might help:
Is switching app.config at runtime possible?
I have an application which is connected to a database through a spring.net AdoTemplate. I am charged with creating a restore database method which keeps the app running but drops the network connections so as to drop the old database and bring up the new one. My question is how do I drop all the current connections that this application has to this AdoTemplate? I do not see any public method in spring 1.1 to drop the network connections.
there is no physical "connection" between AdoTemplate and the SQL database. Leaving transactions aside, AdoTemplate creates a new SqlConnection object for each method that is executed from ADO.NET, executes a command and disposes the SqlConnection object after that.
Under the hoods, ADO.NET caches physical connections to the database in a pool. When you create a new SqlConnection object, 1 of those cached physical connections is obtained from the pool to serve that SqlConnection.
This means, that you will need a different strategy for solving your problem. One strategy coming to my mind is to obtain the list of active connections from the sysprocesses database and execute the KILL statement on them. Short googling brought up this article. Note, that this article refers to mssql 2000. I'm pretty sure, that you need to google a bit more to find a solution for 2005. Since 2005 it isn't allowed to access system tables anymore asfair.
hth,
Erich
What ended up working great was:
SqlConnection.ClearAllPools();
// if any connections were being used at the time of the clear, hopefully waiting
// 3 seconds will give them time to be released and we can now close them as well
Thread.Sleep(3000);
//clear again
SqlConnection.ClearAllPools();