ASP.NET Web サイトで接続にシングルトンを使用することは良い考えですか?
-
21-09-2019 - |
質問
現在、Web アプリケーションでシングルトンを使用しているため、データベースへの接続は常に 1 つだけです。
現在そのエラーで問題が発生しているため、それが良いアイデアかどうか知りたいです。
タイムアウトが経過しました。プールから接続を取得する前にタイムアウト期間が経過しました。これは、プールされたすべての接続が使用中であり、最大プール サイズに達したために発生した可能性があります。
もう 1 つの重要な点は、私の 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 は一度に 1 ユーザーしかサービスを提供できないことになり、アプリケーションの拡張能力が大幅に制限されます。
接続が ない 正しくロックされていると、事態が非常におかしくなる可能性があります。たとえば、あるスレッドが接続を破棄している間に、別のスレッドがその接続に対してコマンドを実行しようとしている場合があります。
接続プーリングを利用するには、単一の接続を使用する代わりに、必要なときに新しい接続オブジェクトを作成する必要があります。
接続プーリングは SqlClient クラスのデフォルトの動作 (そしておそらく他のデータプロバイダーも)。接続プーリングを使用すると、接続を「作成」するたびに、その接続は実際には既存の接続のプールから取得されるため、毎回最初から接続を構築するコストが発生しません。これを解放すると (閉じるか破棄すると)、接続プールに戻されるため、接続の総数は比較的低く抑えられます。
編集:あなたが言及したエラーが表示されます(プールから接続を取得する前に経過したタイムアウト期間) 接続を閉じていない (または破棄していない) 場合。各接続の使用が終了したらすぐにこれを行うようにしてください。
これについて説明したスタック オーバーフローの優れた質問がいくつかあり、役に立つと思います。
他のヒント
いいえ、それは悪い考えです。あなたは、接続プールを使用します。
シングルトンは、恐ろしい考えであるように、データベースへの接続を使用する理由はあります。
シングルトンは、DBに接続するには、唯一のデータベース接続オブジェクトがあることを意味します。二人はそれに接続したいのであれば、彼らはそのオブジェクトにアクセスできるようになるまで待つ必要があります。
それは悪いニュースだ。
ただ、必要なときに、データベース接続オブジェクトの新しいインスタンスを作成しておきます。ここでのトリックはできるだけ遅く接続を開き、できるだけ早くその接続を閉じることです。
データベース接続オブジェクトの中で最も高価な操作は、実際のの接続のです。ない創造ます。
シングルトンは必要ありません。接続プーリングに関する記事は次のとおりです。
.NET 1.1
SQL Server 用の .NET Framework データ プロバイダーの接続プーリング
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0