Opening two SQLConnections with the same ConnectionString - c#

I am tracing a bug in a library I did not write myself. When using this library with ASP.NET, I get db connection errors because the SQLConnection seems to get closed when a second Connection is being opened with the same connection string.
Is this documented behaviour? Can opening a new SQLConnection with the same connection string close another SQLConnection object?
From debugging that seems to be the most likely cause for my problems, but I could not find anything on the web to support my theory.

No, what will happen is that when you call the SqlConnection.Open() method, even with the same connection string parameters, it will do one of two things: either reuse an unused connection from the pool, or create a new connection. Either way, you will result in non-conflicting SPIDs for SQL Server.

Is this documented behaviour?
No.
Can opening a new SQLConnection with the same connection string close another SQLConnection object?
No.
Note that unless you've modified the settings, SQL Server permits 32,767 simultaneous connections. But even then, that would not explain the behavior that you are seeing.

In short, opening a new connection with the same connection string will not close your existing connection. However... reusing the already existing object by creating a new reference to a new connection will destroy the connection.

Related

How can I mantain my connection string alive among the classes

I want to use a connection pooling in my C# project. I understand that one I get the connection to the SQL server, while I'm using the same connection string, the cash pooling will work.
However I have doubts about: how is the best practice to pass the connection string through my different classes? Should I pass the connection string as a parameter to the methods that use it to connect? (for instance each time that I need to do a query)
ADO.NET has built-in connection pooling, and you can't really build a better one.
When you create a connection using a connection string, the Framework checks the connection pool to see if a connection with that connection string is available. If one is, it pulls it from the pool and returns it to you; otherwise, it creates a new one and returns that to you.
Similarly, when you close (dispose of) a connection, it is not immediately destroyed.
When you close a connection with a specific connection string, it is not immediately destroyed. Instead, it is released back into the connection pool.
Automatic connection pooling can be disabled, so that you could roll your own solution, but it's not advisable.
EDIT:
As pointed out, I didn't answer the question in my original answer.
In general, you don't pass connection strings around. Instead, they are stored in a configuration file (either web.config or app.config), in the connectionStrings section. When you need a connection string, you retrieve it within the method that requires it using ConfigurationManager.ConnectionStrings.

Should I create a brand new SqlConnection each time I want to use it, or just attempt to re-open an existing connection each time?

I have a long-running .NET process (a Windows service), which talks to a SQL Server.
Originally, I opened a connection when the service started up, and just kept it open. However, occasionally a network hiccup or reboot of the SQL Server would break that connection, and my process wouldn't know this. It would attempt to keep throwing SQL against a closed connection.
Trying to maintain an open connection like that was clearly me trying to be too clever. So, do I:
Create (and open) a new SqlConnection object every time
Create the connection once on service start-up, and just attempt to re-open the connection every time
For the latter (#2), I have this code:
if(connection.State != ConnectionState.Open)
{
connection.Open();
}
I only have to do this because the connection already exists. If I created the connection fresh each time (#1), clearly it would be closed and I would need to open it.
What I'm hoping to do is take advantage of SQL connection pooling to actually not open a new connection every time, but just let the connection pool manage that -- give me an open connection when it has one, or open a new one when it doesn't.
To achieve this, does it matter if I create the connection fresh each time (#1), or if I just-reuse a connection and attempt to re-open it each time (#2)?
Connection pooling means that even if you do (1), under the hood, the framework will do (2) for you for improved performance. So you can feel free to create a new connection each time.
It's worth pointing out that, for the most part, the pooling only applies to identical connection strings. So if you change certain options, those connections may not be pooled.

ASPX - Storing MysqlConnection in Session

I'm just wondering has anybody tried this. It seems so crazy that I need to open a mysql Connection for every call to the database. Sometimes a page requires 3 of 4 calls to the database and it takes extra time to open the connection.
if I create a new Session class and {get;set}; my connection in that class. Is there any harm in this? Theoretically I would this that performance would be increased. Has anybody tried it? And is there any big setbacks?
The MySql Connector/Net supports connection pooling and this is enabled by default.
Typically, you want to close your connection as soon as possible to avoid using up the pool, so storing the connected MySqlConnection in the session would be a bad idea.
You can manage the session without closing on every call by setting it up in the global.asax Session_start Method then closing it in the Sessions_Stop method.
You cannot store a MySqlConnection in a session. It simply isn't possible. The class isn't even serializable so if you used out-of-proc sessions your application would probably explode with an exception.
You can store a reference to a connection in the application domain by using a global class or Global.asax but with pooling this is needless anyhow, you should allow pooling to manage your connections.

Does DbConnection.Open always open a new database connection or can it reuse one of the connection pool?

I'm unsure at which level the connection pool is implemented in .NET.
When I call
using(var connection = new SqlConnection(connectionString))
{
connection.Open();
Am I surely opening a new connection? Or could I possibly be reusing an active connection?
The connection pool present in SqlConnection can be absent in other DbConnection implementations?
Connection pooling happens automatically, unless you specify otherwise. If you scroll down to the section "Controlling Connection Pooling with Connection String Keywords" in the first link below, you'll see that the default for "pooling" is true.
http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx
Connection pools get created without any intervention by you, as long as the connection string is exactly the same (uppercase/lowercase matters in this point.)
The same can be said for the OleDbConnection and Connection Pooling.
http://msdn.microsoft.com/en-us/library/ms254502.aspx

.NET SqlConnection class, connection pooling and reconnection logic

We have some client code which is using the SqlConnection class in .NET to talk to a SQLServer database. It is intermittently failing with this error:
"ExecuteReader requires an open and available Connection. The connection's current state is Closed"
The "temporary" solution is to reboot the process, after which everything works - however, that's obviously unsatisfactory.
The code is keeping a cache of SqlConnection instances, one for each database.
We'd like to re-write the code, but before I do, I need to know a few things:
My first question is: Is it inefficient to repeatedly connect and disconnect SqlConnection objects, or does the underlying library perform connection pooling on our behalf?
// Is this bad/inefficient?
for(many-times)
{
using(SQLConnection conn = new SQLConnection(connectionString))
{
// do stuff with conn
}
}
Because our code does not do the above, what seems the likely cause of the problem is that something happens to the underlying SQLServer database during the "lifetime" of the connection that causes the connection to be closed...
If it turns out that it is worthwile to "cache" SqlConnection objects, what is the recommended way to handle all errors that could be resolved simply by "reconnecting" to the database. I'm talking about scenarios such as:
The database is taken offline and brought back online, but the client process had no open transactions while this was happening
The database was "disconnected", then "reconnected"
I notice that there is a "State" property on SqlConnection... is there an appropriate way to query that?
Finally, I have a test SQLServer instance set up with full access rights: how can I go about reproducing the exact error "ExecuteReader requires an open and available Connection. The connection's current state is Closed"
No, it's not inefficient to create lots of SqlConnection objects and close each of them when you're done. That's exactly the right thing to do. Let the .NET framework connection pooling do its job - don't try to do it yourself. You don't need to do anything specific to enable connection pooling (although you can disable it by setting Pooling=false in your connection string).
There are many things that could go wrong if you try to cache the connection yourself. Just say no :)
You should enable connection pooling on your connection string. In that case the runtime will add back your connections to the 'pool' when you close them, instead of really disconencting. When a 'new' connection is taken out of the pool it will be reset (ie. sp_reset_connection is called ) then presented to your application as a brand new, fresh connection. The pool is handling transparently such cases as if the connection is closed while idling in the pool.
The cost of creating a new connection 'from scratch' is significant because the authentication requires several roundtrips between client and server (depending on the authentication method and on SSL settings it can be 1 roundtrip in best case vs. about 10 in worse).
And to answer your question, connection raise the OnStateChange event when their state changes, but you shouldn't care about this if you use the pooling.
In my recent experience if you use this code:
using(SQLConnection conn = new SQLConnection(connectionString))
{
// do stuff with conn
}
have an error, and do not explicitly close the connection, it will not be closed or checked back into the pool. So use a catch or finally block to close the connection

Categories

Resources