Spring.net Drop all adotemplate connections? - c#

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();

Related

How to identify processes spawned by a .Net app connecting to POSTGRESQL

I have a C# .net application that connects to a postgresql database.
Experimentation shows that every connection made from the application creates a new postgres.exe process visible in task-manager and traceable in the database.
The C# app has a PID, the postgres connections it spawns also have PIDs, how can the app establish the PID it just created?
I'd like to establish which C# connection results in which database process. I naively assumed that the parent PID of any database connection would match the PID of the application that created the connection. This doesn't appear to be the case.
The best bodge I've managed is to list the postgres.exe processes immediately prior to creating the connection
Process[] processBefore = Process.GetProcessesByName("postgres");
Then make the connection
NpgsqlConnection myDatabaseConnection= new NpgsqlConnection(myConnectionString);
Then list all the postgres processes present afterwards
Process[] processAfter = Process.GetProcessesByName("postgres");
Then compare the two lists and assume that the new process is the one established by the connection.
In practice this seems to work most of the time, but other processes can create (and remove) postgres.exe instances, so there's scope for cock-up.
Is there a better/easier/more reliable way of doing this?
UPDATE - Why do I need to do this? - Fault-finding. I have several different instances of the C# app all making multiple connections to the database. I can monitor all the database sessions, (and their operating system PIDs) from the postgres dashboard. Some of those sessions are running dodgy SQL that's causing problems (conflicts/locks/etc).
Since I don't know the PID of the connection, I can't link the dodgy SQL back to it's source in the app. The basic problem seems to be that although I know the PID of the app, and the app creates the connections, the connection does NOT have a parentPID that matches the app.

Every query on SQLite DB using EF Core in Docker is very slow, unless there is an explicit call to OpenConnection

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

SQLServer AlwaysOn and .net SqlConnection reset

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.

Database level lock in Microsoft SQL Server : schema migrations

I have a distributed application with multiple processes on multiple servers connect to a SQL Server database.
I need to migrate the database schema in code during first startup, because upgrade deployment can be done with the user without database access (we use computer object database access).
Currently this is done by providing a sql file with statements and then a user with db access (but potentially without app access) would run this independently.
Because apps do not talk to each other (firewalls, different DCs etc.) I was thinking that i'd have to designate one server as 'master', all others as 'slaves' and then on the master the first process that'd start would obtain the mutex and do the schema migrations; all others could simply wait until they can see the schema is migrated.
However, this has a certain code smell to me.
I tried researching how Entity Framework handles this in code first migrations and seems they don't (e.g. if two processes start at exact same time they would both try to migrate schema).
Any other approaches?
You can change mode of database to single-user (other connections) will be refused. Make the changes and then change back multi-user mode.
EDIT:
There is trick, how to get "mutex". You can update/delete record(s). Until transaction is open, the exclusive lock is stil holded. Probably, if you delete 0 records (with table-lock hint) from every table in transaction, you probably achieve same behaviour as "global mutex" for the users of database. But I don't know what behaviour will be with schema changes.

How does SQL Server handle Network Failover in the middle of an insert statement

I am writing an Application that executes sql queries on a database in real time.
If I setup mirroring of the SQL Server and setup a FailoverPartner in the connection string and if the primary database goes down, will the secondary kick in automatically and therefore I do not have to re-open a connection or clear anything down?
Also how does it handle situations where a INSERT statement is running and the database goes down? Does the secodary pick it up or is it lost forever? Would it be safer to do transactional based insert statements?
Every form of High Availability (mirroring, clustering) will have a transaction boundary: every transaction in-flight at the moment of failover will be rolled back. This is not a limitation, is a feature. It would be impossible to write correct applications if this would not be true.
When a failover occurs, every connection using the database is cut. The clients have to re-establish new connections with the new principal, read again current state from the database and start applying new operations, on the current state. Correctly written applications (ie. transactional) will not have any issue with this. Only poorly coded apps can lose data.

Categories

Resources