This is a follow up question to: Is it necessary to deconstruct singleton sql connections?
As a few comments there stated it is bad design to use a singleton for sql connection instead of doing multiple usings.
What intrigues me there though is one statement that the performance of the using variant is better than that of the singleton variant. Now as stated by me that it is a bad design is clear to me (I know most pros and cons for singletons there...especially the cons). What surprised me though was the performance statement.
As normally I would think: Ok opening and closing sql connections for 100-1000 times during a programs run SHOULD be less performant than doing this only once. Thus my question is: Is the performance of the non singleton variant really better and if so why?
Singletonexample:
public class SimpleClass
{
// Static variable that must be initialized at run time.
public static SqlConnection singletonConnection;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
static SimpleClass()
{
singletonConnection = new SqlConnection("Data Source.....");
}
}
Usings example:
using (SqlConnection connection = new SqlConnection("Data ..."))
{
....
}
Basically the answer is simple:
Connecting to a database server typically consists of several
time-consuming steps. A physical channel such as a socket or a named
pipe must be established, the initial handshake with the server must
occur, the connection string information must be parsed, the
connection must be authenticated by the server, checks must be run for
enlisting in the current transaction, and so on. In practice, most
applications use only one or a few different configurations for
connections.
This means that during application execution, many
identical connections will be repeatedly opened and closed. To
minimize the cost of opening connections, ADO.NET uses an optimization
technique called connection pooling.
You shouldn't use singleton as some kind of 'performance accelerator' because it is not what it is used for. By using it to store one static SQL connection you are exposing yourself for many memory and connection problems. How you are supposed to close connection? How are you supposed to release memory consumed? When one connection is closed, you are closing it for all application users. How you are planning to reconnect with that approach?
What "connection pooling" basically means is that even if you are creating many SqlConnection objects, as long as they do not differ with connection string, it is possible to reuse existing connection.
Some detailed info can be found there.
Related
I have inherited a .NET desktop application and am trying to track down an intermittant bug where database locks are not being released.
The application takes a Singleton approach to establishing a SQLConnection and I'm wondering if creating and holding open a single instance of a SQLConnection in memory could cause issues in this context?
I know connection pooling makes this code redundant. What I want to know is: given my scenario of each instance of a single-threaded desktop application having a single user, could this approach causes issues?
private static SqlConnection connection;
public static SqlConnection Connection
{
get
{
if (connection == null) {
connection = new SqlConnection();
connection.ConnectionString = "...";
connection.Open();
}
if (connection.State != ConnectionState.Open) {
connection.Open();
}
return connection;
}
}
Edit #1: I know this is not best practice; I know connections should be opened late and closed early; I know connection pooling makes this code redundant. In my specific instance, is an issue demonstrable?
This is an old and obsolete design which is now deprecated in favor of keeping the connectiuon open as little as possible and close and dispose it immediately after each usage witha using clause,
said that the pattern you have shown above should not, only because of itself, create database locks,
consider that even with a connection kept open longer time the connection itself is only a channel so most of the thing depends on the way you use it with Command and Reader objects which when possible you should anyway close and dispose as soon as no longer needed.
If there are some tables locked in the database are you sur ethat is not happening because of multiple users trying to access the same objects at the same time?
Using a Singleton for a SqlConnection object is a really, really bad idea. There is no reason to do this whatsoever.
If you are attempting to avoid a performance hit of "new SqlConnection()" or "connection.Open()" be advised that there really is no performance hit there because of the connection pooling going on behind the scenes. Connection Pooling handles the opening/closing of the expensive connections. Not the SqlConnection object.
You won't be able to open multiple SqlDataReaders/Commands with the connection at the same time and will run into thread blocking issues if you are trying to share the same connection object with multiple threads.
The Singleton pattern is the most over used and abused pattern and there are many side effects of the singleton that you may not be aware of. Very good talk about the dangers of singletons here http://www.youtube.com/watch?v=-FRm3VPhseI
I want to optimize the sql connection in my wep application its create in .net mvc 4, i read that ado.net automatically manager the connection pooling but i'm some lost respect how exactly implement that, is correct if i create a global object with the connection in the Application_Start class then pass the connection object through all data object in my application ? something like this
protected void Application_Start()
{
...
SqlConnection conn = new SqlConnection("Connection String...");
DAOPeople daoPeople = new DAOPeople(conn);
...
}
in that way i avoided create a new SqlConnection for each dao, is correct?
No, don't do that. You'll end up with a bottleneck at your connection object, as that single connection is shared across all sessions and requests to your app.
For connection pooling, you do the exact opposite: don't try to share or re-use a single connection object; do just create a new SqlConnection every time you need it, open it on the spot, and make sure it's disposed as soon as you're done via a using block. Even though your code looks like you're opening and closing a lot of connections, the connection pooling feature is built in and ensures you keep drawing from a small number of existing connections in the same pool.
That said, if you're on a really large site, you can do a little better. One thing large sites will do to help scale is avoid unnecessary memory allocations, and there is some memory that goes with creating an SqlConnection object. Instead they might, for example, have one main SqlConnection per HTTP request, with the possibility of either enabling MARS or having an additional secondary connection object in the request so they can run some things asynchronously. But this is only something the top 0.1% need to care about, and if you're at this level you're measuring to find out where the proper balance is for your particular site and load.
I have a Log class which put logs in Windows journal and in a SQL table. In order to optimize my code, I would like use only one SqlConnection.
In MSDN, it says: Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
My question is :
private static readonly SqlConnection conn = new SqlConnection(ConfigParameters.Instance.UIDConnection);
Is it thread-safe ? If yes, when use Open() and Close()?
If no, how use properly SqlConnection?
Here is my full class code :
private static readonly SqlConnection conn = new SqlConnection(ConfigParameters.Instance.UIDConnection);
public static long WriteLog(string sSource, string sMessage, int iErrorCode, EventLogEntryType xErrorType)
{
// Windows Logs
if (ConfigParameters.Instance.WindowsLog)
EventLog.WriteEntry(sSource, sMessage, xErrorType, iErrorCode);
// SQL Logs
// TODO
return 0;
}
It's not a common way to share a SqlConnection, and it should be used only under special uses cases.
First, You're true that resource pooling is a common pattern used to improve performance when working with sockets, network streams, web services...
But especially for SqlConnection, you don't have to worry about this because the framework already do this for you, thanks to Sql Connection Pool.
Whenever a user calls Open on a connection, the pooler looks for an
available connection in the pool. If a pooled connection is available,
it returns it to the caller instead of opening a new connection. When
the application calls Close on the connection, the pooler returns it
to the pooled set of active connections instead of closing it. Once
the connection is returned to the pool, it is ready to be reused on
the next Open call
You can consider SqlConnection as a wrapper around real connection. Do not beleive that instanciating a new SqlConnection is costly : it's not and many web sites with high trafic are built with it.
The default strategy (for sql server at least) is that it will just work automatically. You just need to be aware of closing your connection (with a using block). There are also many settings to manage the pool.
You code also contains an incorrect error management : if the connection is aborted (DBA, network failure, ...) you will throw exceptions when logging ... not ideal
At this end, I don't think that sharing a sql connection is appropriate in your case. You will gain much more perf using an async logging library.
Do not focus on this now until you're sure it's a real problem.
We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil, Donald Knuth
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SqlConnection Singleton
This is the current code:
static SqlConnection CreateConnection() {
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
return conn;
}
Because the application will only ever need one open connection I'd like to move it into this design pattern. How do I translate the above into the below?
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
I've just picked this pattern from Jon Skeet's site - just went for the fully lazy version as it sounded like the best choice - might not be the correct one though.
There are very few situations were a singleton pattern is appropiated. You have to be sure that there is a mandatory need of one and only one instance of a class instance. Normally you don't have this design requirement, but people tend to make it up.
Connections should be released as soon as you're done with your unit of work. You should not keep a connection open forever so converting your connection to a singleton won't help to improve your application design.
Connection pooling mechanism manage the complexity for you so you don't have to worry about performance in relation to open and close connections since this is optimized by design.
Connecting to a database server typically consists of several time-consuming steps. A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transaction, and so on.
In practice, most applications use only one or a few different configurations for connections. This means that during application execution, many identical connections will be repeatedly opened and closed. To minimize the cost of opening connections, ADO.NET uses an optimization technique called connection pooling.
Connection pooling reduces the number of times that new connections must be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.
Source MSDN
The problem is not singleton, keeping one open connection in application will take down on performance and does not make used of connection concurrency and connection pool.
Technically, you don't need to care how many Connections open as long as they are used with using:
using (var connection = new SqlConnection("yourConnectionString"))
{}
ADO.NET connection pool will take care connections for you automatically.
I have my business-logic implemented in simple static classes with static methods. Each of these methods opens/closes SQL connection when called:
public static void DoSomething()
{
using (SqlConnection connection = new SqlConnection("..."))
{
connection.Open();
// ...
connection.Close();
}
}
But I think passing the connection object around and avoiding opening and closing a connection saves performance. I made some tests long time ago with OleDbConnection class (not sure about SqlConnection), and it definitely helped to work like this (as far as I remember):
//pass around the connection object into the method
public static void DoSomething(SqlConnection connection)
{
bool openConn = (connection.State == ConnectionState.Open);
if (!openConn)
{
connection.Open();
}
// ....
if (openConn)
{
connection.Close();
}
}
So the question is - should I choose the method (a) or method (b) ? I read in another stackoverflow question that connection pooling saved performance for me, I don't have to bother at all...
PS. It's an ASP.NET app - connections exist only during a web-request. Not a win-app or service.
Stick to option a.
The connection pooling is your friend.
Use Method (a), every time. When you start scaling your application, the logic that deals with the state will become a real pain if you do not.
Connection pooling does what it says on the tin. Just think of what happens when the application scales, and how hard would it be to manually manage the connection open/close state. The connection pool does a fine job of automatically handling this. If you're worried about performance think about some sort of memory cache mechanism so that nothing gets blocked.
Always close connections as soon as you are done with them, so they underlying database connection can go back into the pool and be available for other callers. Connection pooling is pretty well optimised, so there's no noticeable penalty for doing so. The advice is basically the same as for transactions - keep them short and close when you're done.
It gets more complicated if you're running into MSDTC issues by using a single transaction around code that uses multiple connections, in which case you actually do have to share the connection object and only close it once the transaction is done with.
However you're doing things by hand here, so you might want to investigate tools that manage connections for you, like DataSets, Linq to SQL, Entity Framework or NHibernate.
Disclaimer: I know this is old, but I found an easy way to demonstrate this fact, so I'm putting in my two cents worth.
If you're having trouble believing that the pooling is really going to be faster, then give this a try:
Add the following somewhere:
using System.Diagnostics;
public static class TestExtensions
{
public static void TimedOpen(this SqlConnection conn)
{
Stopwatch sw = Stopwatch.StartNew();
conn.Open();
Console.WriteLine(sw.Elapsed);
}
}
Now replace all calls to Open() with TimedOpen() and run your program. Now, for each distinct connection string you have, the console (output) window will have a single long running open, and a bunch of very fast opens.
If you want to label them you can add new StackTrace(true).GetFrame(1) + to the call to WriteLine.
There are distinctions between physical and logical connections. DbConnection is a kind of logical connection and it uses underlying physical connection to Oracle. Closing/opening DbConnection doesn't affect your performance, but makes your code clean and stable - connection leaks are impossible in this case.
Also you should remember about cases when there are limitations for parallel connections on db server - taking that into account it is necessary to make your connections very short.
Connection pool frees you from connection state checking - just open, use and immediately close them.
Normally you should keep one connect for each transaction(no parallel computes)
e.g when user execute charge action, your application need find user's balance first and update it, they should use same connection.
Even if ado.net has its connection pool, dispatching connection cost is very low, but reuse connection is more better choice.
Why not keep only one connection in application
Because the connection is blocking when you execute some query or command,
so that means your application is only doing one db operation at sametime,
how poor performance it is.
One more issue is that your application will always have a connection even though your user is just open it but no operations.If there are many user open your application, db server will cost all of its connection source in soon while your users have not did anything.