0

これについては詳細でない質問がたくさんあるので、ここに行きます。

SQL Server 2008 を使用した C# での接続処理のベスト プラクティスは何ですか? SQL Server を呼び出すアセンブリ (この場合は WCF サービスによって使用されます) があります。一般に、これを行うには、接続オブジェクト、コマンド オブジェクト、リーダー オブジェクトの 3 つのオブジェクトが必要なようです。

呼び出しを機能させることができた唯一の信頼できる方法は、次のことです。

  1. 接続を開きます。
  2. using() { } ブロックでコマンドを作成する
  3. 応答を処理するリーダーを作成します。
  4. リーダーを廃棄します。
  5. using() ブロックの最後で Command を暗黙的に破棄する
  6. 接続を閉じます。

同じコマンドを複数回繰り返し実行すると、まだ開いている接続にアタッチされたコマンドまたはリーダー オブジェクトが既に存在するという、異常な問題に遭遇しました。唯一の堅実な解決策は、実行したすべてのコマンドで接続を閉じてから再度開くことでした。反復または順次 (異なるコマンド)。

私はDB接続処理のmysql_pconnectバックグラウンドから来ているので、これが質問です。

  1. コマンドごとに接続を開いたり閉じたりすると、パフォーマンスに大きな影響がありますか?
  2. 1.の場合、適切な回避策、またはコマンドを連続して繰り返すコード構造は何ですか?
  3. 接続、コマンド、またはリーダーを再利用する方法はありますか?
  4. 3. でない場合、これは実際にパフォーマンスやメモリ使用量に大きな影響を与えますか (ユーザーが気付くように)。
4

2 に答える 2

1

@PeterMonksの回答に加えて:

  1. SqlConnection の「高価な」管理されていない部分は、同じ接続文字列を使用している限り、プロバイダー (接続プール) によって再利用されます。そのため、毎回新しいマネージ ラッパーを作成するためのオーバーヘッドはわずかですが、実際には SQL サーバー インスタンスへの接続の作成と 1 対 1 の関係ではないため、思ったほど高価ではありません。

  2. データ リーダーを返すコマンドを連続して繰り返すには、a) 常に同じスレッドでコマンドを実行し (コマンドはスレッド セーフではありません)、b)Close()次のスレッドを作成する前Dispose()DataReaderインスタンスを実行する必要があります。これは、DataReaders を using ブロックにも配置することで実行できます。

リーダーを using ブロックに入れる方法は次のとおりです。

using (var dr = myCommand.ExecuteReader(...)) {
    // Previous discussions have indicated that a close in here, 
    // while seemingly redundant, can possibly help with the error 
    // you are seeing.
    dr.Close();
}

@DavidStratton が言及しているように、もう 1 つの便利なテクニックは MARS を有効にすることですが、結果セットを開いたままにしておくことに関連するオーバーヘッドがあることに注意してください。サーバーとクライアントでの重要なリソース割り当て。

于 2012-04-20T16:24:35.900 に答える
1

ポイント1に答えるために、SqlConnectionのドキュメントを見ると、接続プールについて説明されていることがわかります。これは、SQL Server プロバイダーがすぐに利用できる接続のコレクションを持ち、SqlConnection作成されたそれぞれの接続が次に利用可能な接続を取得することを意味します。したがって、最高のパフォーマンスを得るには、SqlConnectionオブジェクトを作成し続けて短い操作に使用し、その後それらを破棄して接続プールに戻すことをお勧めします。

ポイント3については、SqlConnectionif you doを再利用できると思いますSqlCommand.ExecuteNonQuery()が、を使用するSqlDataReader場合、接続を再利用することはできませんSqlDataReader.

于 2012-04-20T16:14:27.947 に答える