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

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!

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!
Why isn’t SqlConnection
disposed/closed?
What is the proper way to ensure a
SQL connection is closed when an
exception is thrown?

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

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.

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)

Related

Create Database If Not Exist Without Restarting Application

I am creating dynamic connection strings in my project. They're created on the fly with the information provided specifically for every user. When the application first fires off, if a database doesn't exist (first time user logs on), a new database is created without problems with this initializer:
public DataContext() : base()
{
// ProxyCreation and LazyLoading doesn't affect the situation so
// comments may be removed
//this.Configuration.LazyLoadingEnabled = false;
//this.Configuration.ProxyCreationEnabled = false;
string conStr = GetDb();
this.Database.Connection.ConnectionString = conStr;
}
The problem is, with this method, I have to restart the application pool on the server and the new user should be the first accessor to the application.
I need the same thing without a requirement of restarting the app. Is that possible?
(This is a SPA using AngularJS on MVC views and WebApi as data provider - May be relevant somehow, so thought I should mention)
I already tried this, but this creates an error for EF and the application doesn't start at all...
You could try a little bit different approach to connect directly (and create) the right database.
public class DataContext : DbContext
{
public DataContext(DbConnection connection) : base(connection, true) { }
}
Here you create the DbContext already with the right connection.
Take also care because you need to specify to migrations that the right connection should be used (not the Web.Config connection but the connection that raised the database creation).
See the second overload here https://msdn.microsoft.com/en-US/library/hh829099(v=vs.113).aspx#M:System.Data.Entity.MigrateDatabaseToLatestVersion.

does onDisconnect event on SignalR2 releases all of its resources upon disconnect?

I have a concurrent dictionary List on my controller that stores list of online users. For example when Client A and Client B connects there are 2 online clients present on the list, but when i disconnect B and then re- connect again it must still show 2 online clients but in my case, only Client B detected as online user(disconnected then reconnected). I am using IIS server 7.5.. Please help me with this, do i need to use a database rather than dictionary? I think it resets the dictionary to zero if one user disconnects and reconnects again.... :( Below is my hub class code
public class Chat : Hub
{
//add online client
private static ConcurrentDictionary<string, string> personLists
= new ConcurrentDictionary<string, string>();
public void Connect(string Username, int ID)
{
string id = Context.ConnectionId;
if (!personLists.ContainsKey(Username))
{
personLists.TryAdd(Username, id);
Clients.Caller.viewOnlinePersons(personLists.Where(p => p.Key != Username));
Clients.Others.enters(Username);
}
else
{
string notif = "user: "+Username+" is already used";
Clients.Caller.onUse(notif);
}
The concurrent dictionary should work just fine. It'd be good if you could post some code, but if you go this route with concurrent dictionary, make sure it's static (the Hub classes get created and destroyed per signal) and I think it'd be better suited placed on the hub itself and private (and of course static, again). You can also use Dependency Injection with SignalR which will be a lot cleaner.
You'll only need database as a backplane if you plan on running the application on multiple servers where of course a memory of a single server is not accessible by the other servers and a duplicate dictionary would be created for each server, so in that case you need to take the storage and move it up a bit in the architecture to be accessible by all the servers.

Is there a way to set any property on hub that persists throughout the lifetime of a connection?

To set the right context, let me explain the problem. Till RC1, we used to implement GenerateConnectionIdPrefix() to prefix user Id to the connection Id. Then we could retrieve user id from the connection string anytime we need.
With RC2, we now cannot inherit IConnectionIdPrefixGenerator & implement GenerateConnectionIdPrefix anymore. So I was wondering what are other avenues available to set any property on the hub with our data, that persists throughout the lifetime of the connection.
Going through documentation, I realized setting query strings is one way, but that would mean we need to set it for every call. Setting a round trip state might be another option, but it looks like even that is persistent for a single round-trip and not entire lifetime.
So my end goal is set to property once at start on SignalR connection that can be used throughout the connection lifetime.
If there is nothing available now, are there any plans to add support to achieve something similar in next version?
[Update]
As suggested below, I tried to set a state Clients.Caller.Userid in the OnConnected method, then tried to access it in the subsequent call, I found that its null. Both calls are from same connection Id.
Look at the "Round-tripping state between client and server" section on https://github.com/SignalR/SignalR/wiki/Hubs.
Basically you can read and write from dynamic properties on Clients.Caller in Hub methods such as OnConnected or anything invoked by a client. Ex:
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
namespace StateDemo
{
public class MyHub : Hub
{
public override Task OnConnected()
{
Clients.Caller.UserId = Context.User.Identity.Name;
Clients.Caller.initialized();
return base.OnConnected();
}
public void Send(string data)
{
// Access the id property set from the client.
string id = Clients.Caller.UserId;
// ...
}
}
}
State that is stored this way will be persisted for the lifetime of the connection.
If you want to learn how to access this state using the SignalR JS client look at the "Round-tripping state" section of https://github.com/SignalR/SignalR/wiki/SignalR-JS-Client-Hubs.
There are other ways to keep track of users without IConnectionIdPrefixGenerator discussed in the following SO answer: SignalR 1.0 beta connection factory

asp.net webservice OnUnload?

I'm creating a web service which has a number of methods, all of which make use of a SqlConnection. It seems logical that I would declare a class level connection and initialise it in the web service constructor.
Problem is I cannot find a definitive way to release the connection when the web service call completes, so I have a connection leak. I've tried overriding the Dipose() method but it doesn't get called in a reasonable timeframe (actually not at all in my testing). For good measure I also tried attaching a handler to the Disposed() event but as expected same problem.
Is there nothing similar to Page.OnUnload for web service classes? It seems hard to believe I would have to establish a separate connection in every individual method.
Any suggestions?
It seems logical that I would declare a class level connection and initialise it in the web service constructor.
No, this doesn't seem logical at all. ADO.NET uses a connection pooling so that you don't need to do this. This connection pool is per connection string per application domain.
So you could simply draw a new connection from the pool in each web method and return it to the pool at the end (the using statements will take care of this):
[WebMethod]
public void Foo()
{
// Here you are NOT creating a new connection to the database
// you are just drawing one from the connection pool
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
// Here you are NOT opening a new connection to the database
conn.Open();
cmd.CommandText = "SELECT id FROM foo";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something with the results
}
}
} // Here you are NOT closing the connection, you are just returning it to the pool
}
So here's an advice: don't try to manage connections manually by using some class fields, static fields, ... Leave this management to ADO.NET as it does it better.
Remark: The code I've shown usually resides in a data access layer which is called by the web method.

Asp.net ajax update panel sharing a database connection

I have a dropdown box and a literal tag inside an Update Panel. On the selection change event of the dropdown up requery the database and repopulate the literal tag and then call UPdatePanel.Update().
below, is there are way i can avoid having to create a new Oledbconnection each time as this seems slow. Can i reuse and store:
The Datasource
The connection in the page.
if so, how do i keep this state between calls from the GUI to the server? Here is my selection change code below
protected void cboPeople_SelectedIndexChanged(object sender, EventArgs e)
{
string dataSource = ConfigurationSettings.AppSettings["contactsDB"];
var objConn = new OleDbConnection(dataSource);
string id = People[cboPeople.Text];
UpdateLiteral(objConn, id);
}
With .NET is not a good idea to keep your connection alive longer than needs. Good practice would be to put a using statement around it (so it always gets cleaned up):
string dataSource = ConfigurationSettings.AppSettings["contactsDB"];
using(var objConn = new OleDbConnection(dataSource))
{
string id = People[cboPeople.Text];
UpdateLiteral(objConn, id);
}
.NET uses connection pooling, which means that when you close/dispose of the connection it doesn't actually close the connection, rather resets it and add it back to the pool. The next time a connection is needed it is used from the pool. So the overhead is not as much as you think and it is not slow. In actual fact you will find that it will use the same connection as long as only one at a time is needed.
The danger with keeping connections open is that they never get closed, and in high demand situations you run out of connections.
You need to recreate this for each request. You have a a state less server. you never know when or if your client will call back. You do not want to keep an open connection to the database nor could you simply service multiply clients while maintaining one database connection.
To deploy high-performance
applications, you must use connection
pooling. When you use the .NET
Framework Data Provider for OLE DB,
you do not have to enable connection
pooling because the provider manages
this automatically. For more
information about how to use
connection pooling with the .NET
Framework Data Provider for OLE DB,
see OLE DB, ODBC, and Oracle
Connection Pooling (ADO.NET).
From OleDbConnection Class

Resources