在 ASP.NET 网站中使用单例进行连接是一个好主意吗
-
21-09-2019 - |
题
我目前在我的 Web 应用程序上使用单例,以便始终只有一个与数据库的连接。
我想知道这是否是个好主意,因为现在我遇到了这个错误:
超时已过。从池中获取连接之前超时时间已过。发生这种情况的原因可能是所有池连接都在使用中并且已达到最大池大小。
另一个重要的一点是,我的网站目前处于开发阶段,没有很多人继续使用它,所以我不明白为什么会出现此错误!
这是我的单例的代码:
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;
}
}
}
感谢您的帮助!
解决方案
使用单个连接是一个极其糟糕的主意 - 如果对连接的访问被正确锁定,则意味着 ASP.NET 一次只能为一个用户提供服务,这将严重限制您的应用程序的增长能力。
如果连接是 不是 正确锁定,事情会变得非常奇怪。例如,一个线程可能会释放连接,而另一个线程则尝试针对该连接执行命令。
您应该在需要时创建新的连接对象,而不是使用单个连接,以利用连接池。
连接池是 SqlClient 类的默认行为 (可能还有其他数据提供商)。当您使用连接池时,每当您“创建”连接时,该连接实际上都会从现有连接池中拉出,这样您就不会每次都从头开始构建一个连接。当您释放它(关闭它或处置它)时,您将其返回到连接池,从而使连接总数保持相对较低。
编辑:您会看到您提到的错误(从池中获取连接之前超时时间已过)如果您不关闭(或处置)您的连接。确保在使用完每个连接后立即执行此操作。
有几个很好的堆栈溢出问题讨论了这个问题,我怀疑这可能会有所帮助!
其他提示
没有,这是一个坏主意。您使用连接池。
为什么使用连接到数据库中作为单是可怕的想法,其原因是,因为每个第二+连接随后将必须等待要释放的第一个连接。
一个单意味着只有一个数据库连接对象,连接到分贝。因此,如果第二人想连接到它,他们需要等待,直到他们可以访问该对象。
这是个坏消息。
需要时只要保持创建数据库连接对象,的新实例。这里的关键是要尽快尽可能晚地打开连接,然后关闭连接。
在数据库中的连接对象的最昂贵的操作,是实际的连接。不创建。
没有需要一个Singleton。下面是关于连接池一些文章:
<强> .NET 1.1 强>
.NET Framework的数据提供连接池对于SQL Server
<强> .NET 2.0 强>
<强> .NET 3.0 强>
<强> .NET 3.5 强>
<强> .NET 4.0 强>