4

コードを再配置して、ADO 接続を「プール」するよう提案されました。各 Web ページで、1 つの接続を開き、開いている同じ接続を使用し続けます。しかし、10 年前は重要だったが、今はそれほど重要ではないという人もいました。たとえば、Web 投稿で 5 db の呼び出しを行った場合、開いたり閉じたりする 5 つの個別の接続を使用することは問題になりますか?

4

6 に答える 6

3

SQL Server で ADO.NET を使用している場合、接続は既にプールされている可能性があります。接続プーリングは、最近のデータベースでは非常に一般的な方法であり、ほとんどの場合、知らないうちにプーリングを使用しています。私の推測では、接続を手動でプールすることは、現在は一般的に自動化されているため、それほど重要ではないと言われたと思います。

いくつかの理由から、これは良い習慣です。1 つには、接続の作成には一定の時間が必要であり、接続を頻繁に閉じたり開いたりすると、貴重な時間が無駄になる可能性があります。第 2 に、接続は多くの場合有限のリソースであり、無駄にすべきではありません。多くの場合、スタック レベルの制限により、接続を開く頻度が妨げられることもあります。高スループット環境では、実際に接続を開いたり閉じたりすると、有限のリソースが使い果たされ、ゆっくりと再び利用できるようになるため、ボトルネックが発生する可能性があります。

于 2010-03-13T22:16:44.433 に答える
3

SQL Server への接続は、ASP.NET アプリケーションに自動的にプールされます。個別の接続文字列ごとに 1 つのプールです。ベスト プラクティスに従い、接続文字列がアプリケーション全体で一定である DAL にデータベース コードを隠しておくと、常に接続オブジェクトの1 つのプールで作業することになります。

では、これはデータベースへのアプローチにとって何を意味するのでしょうか? 1 つには、"接続を閉じる" ということは、実際にはアプリケーションの SQL Server へのリンクを閉じるのではなく、"接続をプールに戻す" ということです。したがって、閉鎖と再開はそれほど大したことではありません。ただし、そうは言っても、ここに従うべきいくつかのベスト プラクティスがあります。

まず、アプリが大幅にスケールアップしたとしても、プール内の接続が不足することは望ましくありません。つまり、「このページのユーザー」という順番で考えてはいけません。「このページを使用している千人の人々」という言葉で考えてください。

第二に、接続を閉じて再度開くのはそれほど負担ではありませんが、通常はできるだけ遅く接続を開き、完了するまで使用してからできるだけ早く閉じたいと思うでしょう。唯一の例外は、一部のデータを取得した、他のデータを保存または取得する前に行う必要がある時間のかかるプロセスがある場合です。

第三に、ページのライフサイクルの早い段階で接続を開き、別の方法でライフサイクルの後半に接続を閉じることを強くお勧めします。なんで?接続を閉じるためのロジックを追加するのを忘れて接続を開いたままにしておくのは、最悪の場合です。はい、最終的には GC が開始されると閉鎖されますが、繰り返しますが、「このページを使用している 1,000 人* のことを考えると、実際に問題が発生する可能性が明らかになります。

ここで、接続を閉じるのは確実であると言ったらどうなるでしょうか。なぜなら、常に重要で論理的な場所 (Page_Unload メソッドなど) で接続を閉じるからです。ページのライフサイクルから飛び出すようなエラーを決してスローしないと自信を持って言える限り、これは素晴らしいことです。 あなたができないこと。そのため、ページ ライフサイクルのあるメソッドで開いて、別のメソッドで閉じないでください。

最後に、データベース接続を管理し、データを操作するためのツールを提供する DAL を実装することを強くお勧めします。その上で、これらのツールを使用してタイプ セーフなオブジェクト (「モデル」オブジェクトなど) を UI に提供するビジネス ロジック層 (BLL) を構築します。IDisposable インターフェイスを使用して BLL オブジェクトを実装すると、スコープを使用して常に接続の安全性を確保できます。また、データベース接続を非常に短時間開いたままにすることもできます。BLL オブジェクトを開き、データをローカル オブジェクトまたはリストにプルしてから、BLL オブジェクトを閉じます (スコープ外に出ます)。接続が閉じられた、BLL によって返されたデータを操作できます。

では、これはどのように見えるでしょうか。ページ(UI)では、次のようなビジネス ロジック クラスを使用します。

using (BusinessLogicSubClass bLogic = new BusinessLogicSubClass())
{
   // Retrieve and display data or pull from your UI and update
   // using methods built into the bLogic object
    .
    .
    .
}  // <-- Going out of scope will automatically call the dispose method and close the database connection.

BusinessLogicSubClass は、IDisposable を実装する BusinessLogic オブジェクトから派生します。DAL クラスをインスタンス化し、次のように接続を開きます。

public class BusinessLogic : IDisposable
{
    protected DBManagementClass qry;
    public BusinessLogic()
    {
        qry = new DBManagementClass();
    }

    public void Dispose()
    {
        qry.Dispose();  <-- qry does the connection management as described below.
    }

    ... other methods that work with the qry class to 
    ... retrieve, manipulate, update, etc. the data 
    ... Example: returning a List<ModelClass> to the UI ...

 }

BusinessLogic クラスがスコープ外になると、IDisposable インターフェイスを実装する Dispose メソッドが自動的に呼び出されます。

DAL クラスには、一致するメソッドがあります。

public class DBManagementClass : IDisposable
{
    public static string ConnectionString { get; set; }  // ConnectionString is initialized when the App starts up.

    public DBManagementClass()
    {
        conn = new SqlConnection(ConnectionString);  
        conn.Open();
    }

    public void Dispose()
    {
        conn.Close();
    }

    ... other methods
}

これまで説明してきたことを考えると、DAL はIDisposable である必要はありません。ただし、新しい BLL メソッドをテストするときに、テスト コードで DAL クラスを広範囲に使用するため、DAL を IDisposable として構築し、テスト中に "using" コンストラクトを使用できるようにしました。

このアプローチに従えば、本質的に、接続プーリングについて二度と考える必要がなくなります。

于 2010-03-13T23:11:47.057 に答える
3

フレームワーク 2.0 以降、ASP.NET は既定で SQL Server への接続をプールします。

しかし、あなたが話した人々が話していることは、正確にはプーリングではありません. むしろ、データベース セッションの数を減らすことです。

接続がプールされるため、接続オブジェクトを閉じて別の接続オブジェクトを開くことによるペナルティは非常に小さくなります。通常、データベース接続自体が接続プールに返され、次の接続オブジェクトを作成すると、返されたのと同じ接続を使用してデータベース接続が再確立されます。

それでも、接続が再確立されるたびにデータベースに対して要求が行われるため、合理的に可能であれば、使用する接続オブジェクトの数を減らすようにしてください。

ページ サイクルにより、すべてのデータベース操作に対して接続オブジェクトを開いたままにしておくことが少し難しくなります。そのため、私が通常行うことは、Page_Load で行われるデータの定期的なフェッチに 1 つの接続オブジェクトを使用し、次に必要な場合は別の接続を使用することです。データベース内のデータを更新するためのボタン イベント。

于 2010-03-13T22:40:28.017 に答える
2

何かへの接続をプールするのは良い考えだと思います。ほとんどすべてのものには、有限の接続制限があります。さらに、接続を開くことに関連するオーバーヘッドがあるため、同じ接続を使用する方がはるかに効率的で、応答時間が節約されます。

15 のデータベース呼び出しにスケーリングするとどうなるでしょうか? それらの接続が積み重なっていきます。

それらをプールします。しない理由はありません。

確かに、最近のサーバーは何でもかじることができますが、節約できる応答時間はユーザー エクスペリエンスを向上させます。

于 2010-03-13T22:12:58.587 に答える
2

とにかく、ADO.NET は多くの場合、接続をプールします。これは良いことだと考えられることもあります。正しいことをしようと懸命に努力し、おそらく何の悲しみも引き起こさないでしょう。

毎回同じパラメーターで接続を作成することを除いて、これを達成するために特別なことをする必要はありません (これは難しくありません。各ページで同じルーチンを使用して接続を作成するだけです)。

もちろん、プールされた接続は、異常な場合に問題を引き起こす可能性があります。その場合、接続を無効にすることをお勧めしますしかし、それ以外の場合は、そのままにしておくだけでうまくいくはずです。

于 2010-03-13T22:21:51.407 に答える
1

私が見つけた重要なことは、データベース接続の作成にかかる時間です。

地球の反対側にある低速接続の MSSQL Server の場合、プーリングによってアプリの応答性が著しく向上します。

ローカルの MySQL インストールの場合、大きな違いは見られない場合があります。

于 2010-03-13T22:13:42.547 に答える