Do ConnectionPools have one connection, or many? - c#

We have a web server which connects to a database using a single connection string, which makes it a strong candidate for being able to use a Connection Pool.
Do we need one SqlConnection object, or many?
i.e. Should we set up one connection in shared memory, and use that each time, or should we create a new one each time we want to use any connection object?
Is it the call to .Open() which assigns it from a pool, or the creating of a new object with the same connection string?
Also, do we need to call .Close() on the connection before it's released back into the pool, or is the variable going out of scope enough?
I read somewhere (I forget where exactly - sorry) that you shouldn't call close on connections in a pool, because it removes them from the pool somehow.

It’s worth bearing in mind that an identical connection string will re-use a connection which has been returned the the pool, but changing it in any way will cause a new connection to be made to the server.
i.e.
Assuming that SQLBox has IP 10.0.0.1
using (var conn = new SqlConnection(#"Server=10.0.0.1;...") {
conn.Open();
.. Do work ..
conn.Close();
}
using (var conn = new SqlConnection(#"Server=SQLBox;…") {
conn.Open(); // This will *NOT* reuse the connection from the pool.
.. Do work ..
conn.Close();
}
using (var conn = new SqlConnection(#"Server=10.0.0.1;...") {
conn.Open(); // This *WILL* reuse the connection from the pool.
.. Do work ..
conn.Close();
}

You should open a separate connection every time you need to access a database and close it once you're done with all the access. Do not keep your connections open for too long. It is not necessary and modern databases are definitely very good at handling multiple connections.
You can leave the management of the connection pool to SQL Server - it will do a good job as long as you'll not try to prevent it.
It's best to use local connection object and not share it across multiple parts of the code. You can use using pattern to make sure your connection will be closed:
using (SqlConnection conn = new SqlConnection("connectionstring"))
{
conn.Open();
// use your connection here
}

Related

How to keep single SQL Server connection instance open for multiple request in C#?

I have a Web API which contains database insert logic (ado.net) in C#. When multiple users (e.g. 100 users) call the Web API, every time a SQL Server connection is opened and closed for multiple requests. It slows down performance.
How can I keep a single SQL Server connection live for multiple requests? I have to keep SQL connection open only once and close after some time so that during that time it should consider multiple request and insert records in database.
Please suggest.
ADO.NET's SqlConnection is implementing a connection pool.
This means that when you close or dispose an instance of SqlConnection, the underlying connection simply returns to the pool. When another instance of SqlConnection is opened, and a connection is available in the connection pool, that connection will be used.
In fact, Microsoft docs page on SQL Server Connection Pooling clearly states:
Caution
We strongly recommend that you always close the connection when you are finished using it so that the connection will be returned to the pool. You can do this using either the Close or Dispose methods of the Connection object, or by opening all connections inside a using statement in C#, or a Using statement in Visual Basic. Connections that are not explicitly closed might not be added or returned to the pool. For more information, see using Statement or How to: Dispose of a System Resource for Visual Basic.
This means that the best practice way of using SqlConnection is this:
using(var con = new SqlConnection(connectionString))
{
// your sql stuff goes here...
}
BTW, SqlCommand, SqlDataReader and SqlDataAdapter also implements the IDisposable interface, so they too needs to be used in the context of the using statement:
using(var con = new SqlConnection(connectionString))
{
using(var cmd = new SqlCommand(sql, con))
{
// prepare command here - parameters and stuff like that
// either
using(var reader = cmd.ExecuteReader())
{
}
// or
using(var adapter = new SqlDataAdapter(cmd))
{
}
}
}
Well it's easy you just have to keep the connection open and if any readers opened they are closed.
var con = new SqlConnection("Your connection String");
con.open();
//your code
con.close()//after you have done your executions
Have you tried Linq. It does the same thing you want, it keeps the connection alive and i think it'll be easier for you

C# Closing Database Connections

I need a to get a bit of understanding in this, When you open a connection to a Database can you leave it open?
How does this connection close?
Is it good practise or bad practice?
Currently I have a request to a database that works no problem
oCON.Open();
oCMD.ExecuteNonQuery();
oCON.Close();
However Some of the examples that I have seen are something like this with no database close.
oCON.Open();
oCMD.ExecuteNonQuery();
How would this connection get closed?
Is this bad practice?
I was looking for a duplicate, as this seems to be a common question. The top answer I found is this one, however, I don't like the answer that was given.
You should always close your connection as soon as you're done with it. The database has a finite number of connections that it allows, and it also takes a lot of resources.
The "old school" way to ensure the close occurred was with a try/catch/finally block:
SqlConnection connection;
SqlCommand command;
try
{
// Properly fill in all constructor variables.
connection = new SqlConnection();
command = new SqlCommand();
connection.Open();
command.ExecuteNonQuery();
// Parse the results
}
catch (Exception ex)
{
// Do whatever you need with exception
}
finally
{
if (connection != null)
{
connection.Dispose();
}
if (command != null)
{
command.Dispose();
}
}
However, the using statement is the preferred way as it will automatically Dispose of the object.
try
{
using (var connection = new SqlConnection())
using (var command = new SqlCommand())
{
connection.Open();
command.ExecuteNonQuery();
// Do whatever else you need to.
}
}
catch (Exception ex)
{
// Handle any exception.
}
The using statement is special in that even if an exception gets thrown, it still disposes of the objects that get created before the execution of the code stops. It makes your code more concise and easier to read.
As mentioned by christophano in the comments, when your code gets compiled down to IL, it actually gets written as a try/finally block, replicating what is done in the above example.
You want your SqlConnection to be in a using block:
using(var connection = new SqlConnection(connectionString))
{
...
}
That ensures that the SqlConnectionwill be disposed, which also closes it.
From your perspective the connection is closed. Behind the scenes the connection may or may not actually be closed. It takes time and resources to establish a SQL connection, so behind the scenes those connections aren't immediately closed. They're kept open and idle for a while so that they can be reused. It's called connection pooling. So when you open a connection, you might not really be opening a new connection. You might be retrieving one from the connection pool. And when you close it, it doesn't immediately close, it goes back to the pool.
That's all handled behind the scenes and it doesn't change what we explicitly do with our connections. We always "close" them as quickly as possible, and then the .NET Framework determines when they actually get closed. (It's possible to have some control over that behavior but it's rarely necessary.)
Take a look at the Repository Pattern with Unit of Work.
A connection context should be injected into the class which operates commands to the database.
A sql execution class - like a repository class represents - should not create a connection. It is not testable and hurts the paradigm of SRP.
It should accept an IDbConnection object like in the constructor. The repository should not take care if behind the IDbConnection is an instance of SqlConnection, MysqlConnection or OracleConnection.
All of the ADO.NET connection objects are compatible to IDbConnection.

Should my db connection be left open and passed around in asp.net or open and closed as needed?

I am working on a unit of work class and I'm curious how the connection should be handled. My repositories take in a unit of work, and use that connection for Get() commands.
Obviously, Commit() will handle all Add, Updates and Deletes. This would open the connection and begin the transaction and close when finished. How should Gets be handled?
Should the UOW, open the connection in the constructor and close when completely finished? Meaning while I pass UOW from repo to repo, the connection is open. Or should I be opening and closing it only as needed?
Approach #1: Unit of work opens connection and connection remains open until processing is finished?
public UnitOfWork(IDbConnection connection)
{
Connection = connection;
Connection.Open();
Transaction = Connection.BeginTransaction();
}
Approach #2: Snippet of a Get method that opens right before read and closes right after. If passing to multiple repos, same connection is used, just opened and closed a bunch.
using (var reader = manager.GetReader())
{
UOW.Connection.Open();
while (reader.Read())
list.Add(factory.CreateTFromReader(reader));
UOW.Connection.Close();
}
No, you should always open the connection when needed and be absolutely sure to close it when the work is complete. The Connection Pooling mechanism will take care of keeping the connection available for your current user or for other users connecting concurrently on the same server
I think also that the second example is not quite right. You should have something like this
using (IDbConnection cn = manager.GetConnection)
using (var reader = manager.GetReader())
{
cn.Open();
while (reader.Read())
list.Add(factory.CreateTFromReader(reader));
}
This will ensure that the connection is closed even in the event of exceptions, and that is returned to the pool in order to be reused
Connection Pooling

How to Close Sqlite Connection without explicitly calling Close Method using .NET

I am creating desktop application in winform that will use Sqlite Database.
So I created Sqlite Helper class that uses System.Data.SQLite and each method of that Helper class opens and closes connection.
But now I also added ability to attach additional databases but after Connection is Closed, all attached databases gets lost.
To correct this I modified the class so that the connection is opened in constructor and remains open.
After the application ends, I want that connection to close without explicitly calling the Close method.
Any suggestions how to do that?
Keeping the connection open for the lifetime of your application is not a good way to go.
I suggest to not follow this route.
On the contrary, I will try to encapsulate the functionality to attach a database inside a method that could be called on the need to use basis.
For example:
private static void AttachDB(string fileDB, string aliasName, SQLiteConnection cn)
{
string sqlText = string.Format("ATTACH '{0}' AS {1}", fileDB, aliasName)
SQLiteCommand cmd = new SQLiteCommand(sqlText, cn)
cmd.ExecuteNonQuery();
}
then in your code
using(SQLiteConnection cn = new SQLiteConnection(GetConnectionString()))
{
AttachDB(#"C:\SQLite\UserData.sqlite3", "UserData", cn);
// Do your code here
}
Close should not disconnect your database but this will only work when .NET connection pooling mechanism is on. Make sure you have that enabled in your connection string:
Data Source=filename;Version=3;Pooling=True;Max Pool Size=100;
Depending on how your class is defined, you can use Dispose or a destructor. Or, explicitly call Close() at the end of the program (from within Main, after Run...).
In C# there is a special syntax for such situation:
using(var connection = new Connection())
{
//work with connection
}
it compiles to something like:
Connection connection = null;
try
{
connection = new Connection();
//your operations
}
finally
{
connection.Dispose();
}
on calling Dispose() you close connection.

SqlConnection and the Pool, is keeping an open connection kung-foo or foo-bar?

I had thought I was clever. But in light of recent discoveries, I'm not so sure any more. During the page life cycle, there could by any number of database interactions. Some back to back, others spread out. So I invented an object that keeps an instance of an SQL connection alive in the HttpContext.Items dictionary. Every db request then uses this connection and when the http request has ended, I properly dispose of the connection. We're looking at a couple hundred milliseconds the connection would be open, and with some heavy http caching, running out of available connections isn't a concern.
The point was to prevent additional round trips due to the establishing of new connections. But when I stumbled upon the knowledge of connection pooling, I think it pretty invalidates the usefulness of preserving the SqlConnection. Or does it?
Is scenario A the same as Scenario B, performance wise? Which would you recommend? Does scenario B provide no performance gains, and even possibly hinders it because of some edge cases where the connection might not disposed of properly? Forgive the pseudo-ness in the examples, I don't want to clutter them with barf.
A
using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand("...", connection))
{
... doing database stuff ...
}
}
... traversing the stack ...
using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand("...", connection))
{
... doing database stuff ...
}
}
B
var connectionKeeper = new ConnectionKeeper();
// Add to the context items so it can be used anywhere
Context.Items.Add("Connection", connectionKeeper);
... traversing the stack ...
using (var command = new SqlCommand("...", connectionKeeper.Connection))
{
... doing database stuff
}
... traversing the stack ...
using (var command = new SqlCommand("...", connectionKeeper.Connection))
{
... doing database stuff
}
... traversing the stack ...
// The end of the request
sqlKeeper.Dispose();
Use your code from section A. Please let the connection pool do it's job. Avoid keeping a static SqlConnection around at all costs. The connection pool was designed for this.
Here's an MSDN article for your reference.
SQL Server Connection Pooling (ADO.NET)
No point in doing that in code unless you turn connection pooling off.
And you should have a real serious think before doing that, that's extreme circumstances.
Connection pooling was invented to address the situation you are trying to address with this "permanent" connection, so it will actually interfere with the built in optimisations and increase the volume, complexity, and fragility of your code.

Categories

Resources