7

我目前在我的 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;
        }
    }
}

谢谢你的帮助!

4

4 回答 4

25

使用单个连接是一个非常糟糕的主意 - 如果对连接的访问​​被正确锁定,则意味着 ASP.NET 一次只能为一个用户提供服务,这将严重限制您的应用程序的增长能力。

如果连接没有正确锁定,事情会变得非常奇怪。例如,一个线程可能会在另一个线程尝试对其执行命令时释放连接。

您应该只在需要时创建新的连接对象,而不是使用单个连接,以利用连接池。

连接池是SqlClient 类(可能还有其他数据提供者)的默认行为。当您使用连接池时,任何时候“创建”连接时,实际上都会从现有连接池中提取连接,这样您就不会产生每次从头开始构建连接的成本。当您释放它(关闭它或丢弃它)时,您将它返回到连接池,从而使您的连接总数保持相对较低。


编辑:如果您没有关闭(或处置)您的连接,您将看到您提到的错误(从池中获取连接之前已过去的超时时间)。确保在使用完每个连接后立即执行此操作。

有几个很好的堆栈溢出问题可以讨论这个问题,我怀疑这可能会有所帮助!

于 2009-10-13T00:11:21.993 回答
8

不,这是个坏主意。您使用连接池。

于 2009-10-13T00:03:50.283 回答
4

将数据库连接用作单例的原因是一个可怕的想法,因为每个第二个以上的连接都必须等待第一个连接被释放。

单例意味着只有一个数据库连接对象可以连接到数据库。因此,如果第二个人想要连接到它,他们需要等到他们可以访问该对象。

这是个坏消息。

只需在需要时继续创建数据库连接对象的新实例。这里的技巧是尽可能晚地打开连接,然后尽快关闭该连接。

数据库连接对象中最昂贵的操作是实际连接。不是创造。

于 2009-10-13T00:12:02.390 回答
3

不需要单例。以下是一些关于连接池的文章:

.NET 1.1

适用于 SQL Server 的 .NET Framework 数据提供程序的连接池

.NET 2.0

在 SQL Server 中使用连接池

.NET 3.0

使用连接池

.NET 3.5

SQL Server 连接池 (ADO.NET)

.NET 4.0

SQL Server 连接池 (ADO.NET)

于 2009-10-13T00:27:40.527 回答