Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using a singleton for the connection a good idea in ASP.NET website

I'm currently using a singleton on my web application so that there is always only one connection to the database.

I want to know if it's a good idea because right now I'm having trouble with that error:

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

Another important point is that my website is currently in dev and not a lot of people go on it so I don't understand why I get this error!

Here is the code of my singleton:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

/// <summary>
/// This class take care of all the interaction with the database
/// </summary>
public class DatabaseFacade
{
    SqlConnection m_conn = null;

    string m_csLanguageColumn;

    //Variables that implement the Singleton pattern
    //Singleton pattern create only one instance of the class
    static DatabaseFacade instance = null;
    static readonly object padlock = new object();

    /// <summary>
    /// Private constructor. We must use Instance to use this class
    /// </summary>
    private DatabaseFacade()
    {
    }

    /// <summary>
    /// Static method to implement the Singleton
    /// </summary>
    public static DatabaseFacade Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new DatabaseFacade();
                }
                return instance;
            }
        }
    }

    /// <summary>
    /// Do the connection to the database
    /// </summary>
    public void InitConnection(int nLanguage)
    {
        m_conn = new SqlConnection(GetGoodConnectionString());

        try
        {
            //We check if the connection is not already open
            if (m_conn.State != ConnectionState.Open)
            {
                m_conn.Open();
            }

            m_csLanguageColumn = Tools.GetTranslationColumn(nLanguage);

        }
        catch (Exception err)
        {
            throw err;
        }
    }
}

Thanks for your help!

like image 649
Jean-François Côté Avatar asked Oct 13 '09 00:10

Jean-François Côté


People also ask

Should connections be Singleton?

A DB connection should not normally be a Singleton. Two reasons: many DB drivers are not thread safe. Using a singleton means that if you have many threads, they will all share the same connection.

Should I use Singleton or scoped?

Scoped services service is the better option when you want to maintain state within a request. Singletons are created only once and not destroyed until the end of the Application. Any memory leaks in these services will build up over time.

What is Singleton in asp net?

Singleton is a design pattern, It means that there will be a single copy of your object inside server memory, which will be shared among all the requests (http/client). So, when you register any dependency in your application as a Singleton, then you will get a single copy of an object per server/node/instance.


4 Answers

Using a single connection is an extremely bad idea - if access to the connection is properly locked, it means that ASP.NET can only serve one user at a time, which will seriously limit your application's ability to grow.

If the connection is not properly locked, things can get really weird. For example, one thread might dispose the connection while another thread is trying to execute a command against it.

Instead of using a single connection, you should just create new connection objects when you need them, to take advantage of connection pooling.

Connection pooling is the default behavior for the SqlClient classes (and probably other data providers). When you use connection pooling, any time you 'create' a connection, the connection will actually be pulled from a pool of existing ones so that you don't incur the costs of building one from scratch each time. When you release it (close it or dispose of it) you return it to the connection pool, keeping your total count of connections relatively low.


Edit: You'll see the error you mention (The timeout period elapsed prior to obtaining a connection from the pool) if you're not closing (or disposing) your connections. Make sure you do that as soon as you're done using each connection.

There are several good stack overflow questions that discuss this, which I suspect might be helpful!

like image 171
Jeff Sternal Avatar answered Oct 25 '22 11:10

Jeff Sternal


No, it's a bad idea. You use connection pooling.

like image 33
Noon Silk Avatar answered Oct 25 '22 11:10

Noon Silk


The reason why using a Connection to the database as a singleton is an horrific idea, is because every 2nd+ connection will then have to WAIT for the first connection to be released.

A singleton means that there's only one database connection object, to connect to the db. So if a second person wants to connect to it, they need to wait until they can access that object.

That's bad news.

Just keep creating new instances of the database connection object, when required. The trick here is to open the connection as late as possible and then close that connection as soon as possible.

The most expensive operation in a database connection object, is the actual connection. not the creation.

like image 33
Pure.Krome Avatar answered Oct 25 '22 10:10

Pure.Krome


No need for a Singleton. Here are some articles on connection pooling:

.NET 1.1

Connection Pooling for the .NET Framework Data Provider for SQL Server

.NET 2.0

Using Connection Pooling with SQL Server

.NET 3.0

Using Connection Pooling

.NET 3.5

SQL Server Connection Pooling (ADO.NET)

.NET 4.0

SQL Server Connection Pooling (ADO.NET)

like image 21
rick schott Avatar answered Oct 25 '22 10:10

rick schott