Является ли использование единого для подключения хорошей идеей на веб-сайте ASP.NET
В настоящее время я использую в своем веб-приложении синглтон, так что всегда есть только одно соединение с базой данных.
Я хочу знать, если это хорошая идея, потому что сейчас у меня проблемы с этой ошибкой:
Тайм-аут истек. Период ожидания истек до получения соединения из пула. Это могло произойти из-за того, что все пул соединений использовались и был достигнут максимальный размер пула.
Другим важным моментом является то, что мой веб-сайт в настоящее время находится в разработке, и мало кто заходит на него, поэтому я не понимаю, почему я получаю эту ошибку!
Вот код моего синглтона:
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;
}
}
}
Спасибо за вашу помощь!
4 ответа
Использование одного соединения - крайне плохая идея - если доступ к соединению должным образом заблокирован, это означает, что ASP.NET может одновременно обслуживать только одного пользователя, что серьезно ограничит возможности вашего приложения для роста.
Если соединение не заблокировано должным образом, все может стать очень странным. Например, один поток может удалить соединение, в то время как другой поток пытается выполнить команду против него.
Вместо того, чтобы использовать одно соединение, вы должны просто создавать новые объекты соединения, когда они вам нужны, чтобы использовать преимущества пула соединений.
Пул соединений является поведением по умолчанию для классов SqlClient (и, возможно, других поставщиков данных). Когда вы используете пул соединений, каждый раз, когда вы "создаете" соединение, оно будет фактически извлечено из пула существующих, так что вы не будете нести затраты на его создание каждый раз. Когда вы отпускаете его (закрываете или удаляете), вы возвращаете его в пул соединений, сохраняя при этом общее количество соединений относительно низким.
Изменить: вы увидите упомянутую ошибку (времяожидания истекло до получения соединения из пула), если вы не закрываете (или не удаляете) свои соединения. Убедитесь, что вы делаете это, как только вы закончите, используя каждое соединение.
Есть несколько хороших вопросов о переполнении стека, которые обсуждают это, что я подозреваю, может быть полезным!
Причина, по которой использование Соединения с базой данных в качестве одиночного является ужасной идеей, заключается в том, что каждое второе соединение + затем будет ДОЛЖНО ЖДАТЬ первого соединения, которое будет освобождено.
Синглтон означает, что есть только один объект подключения к базе данных, чтобы подключиться к БД. Поэтому, если второй человек хочет подключиться к нему, ему нужно подождать, пока он не сможет получить доступ к этому объекту.
Это плохие новости.
Просто продолжайте создавать новые экземпляры объекта подключения к базе данных, когда это необходимо. Хитрость заключается в том, чтобы открыть соединение как можно позже, а затем закрыть его как можно скорее.
Самая дорогая операция в объекте соединения с базой данных - это фактическое соединение. не творение.
Нет необходимости в синглтоне. Вот несколько статей о пуле соединений:
.NET 1.1
Пул соединений для провайдера данных.NET Framework для SQL Server
.NET 2.0
Использование пула соединений с SQL Server
.NET 3.0
Использование пула подключений
.NET 3.5
Пул соединений с SQL Server (ADO.NET)
.NET 4.0