7

現在、Webアプリケーションでシングルトンを使用しているため、データベースへの接続は常に1つだけです。

今私はそのエラーで問題を抱えているので、それが良い考えかどうか知りたいです:

タイムアウトが期限切れになりました。プールから接続を取得する前にタイムアウト期間が経過しました。これは、プールされたすべての接続が使用されていて、最大プールサイズに達したために発生した可能性があります。

もう1つの重要な点は、私のWebサイトは現在開発中であり、多くの人が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 は一度に 1 人のユーザーしかサービスを提供できず、アプリケーションの拡張能力が大幅に制限されます。

接続が適切にロックされていない場合、事態は非常に奇妙になります。たとえば、あるスレッドが接続を破棄し、別のスレッドがその接続に対してコマンドを実行しようとしている場合などです。

単一の接続を使用する代わりに、必要なときに新しい接続オブジェクトを作成して、接続プールを利用する必要があります。

接続プールは、SqlClient クラス(およびおそらく他のデータ プロバイダー) の既定の動作です。接続プーリングを使用すると、接続を「作成」するたびに、接続は実際には既存のプールからプルされるため、毎回ゼロから作成するコストが発生しません。それを解放する (閉じるか破棄する) と、それを接続プールに戻し、接続の合計数を比較的少なく保ちます。


編集:接続を閉じていない(または破棄していない)場合、言及したエラー(プールから接続を取得する前にタイムアウト期間が経過しました)が表示されます。各接続を使い終わったらすぐにそれを行うようにしてください。

これについて議論するいくつかの良いスタック オーバーフローの質問があります。

于 2009-10-13T00:11:21.993 に答える
8

いいえ、それは悪い考えです。接続プールを使用します。

于 2009-10-13T00:03:50.283 に答える
4

データベースへの接続をシングルトンとして使用することが恐ろしい考えである理由は、最初の接続が解放されるのを 2 回以上の接続ごとに待機する必要があるためです。

シングルトンとは、データベースに接続するためのデータベース接続オブジェクトが 1 つしかないことを意味します。そのため、別の人がそれに接続したい場合は、そのオブジェクトにアクセスできるようになるまで待つ必要があります。

それは悪いニュースです。

必要に応じて、データベース接続オブジェクトの新しいインスタンスを作成し続けます。ここでの秘訣は、できるだけ遅く接続を開き、できるだけ早くその接続を閉じることです。

データベース接続オブジェクトで最もコストのかかる操作は、実際の接続です。創造ではありません。

于 2009-10-13T00:12:02.390 に答える
3

シングルトンは必要ありません。接続プーリングに関するいくつかの記事を次に示します。

.NET 1.1

.NET Framework Data Provider for SQL Server の接続プール

.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 に答える