2012-03-20 13 views
4

多くの異なるsqlコマンドを実行していて、SqlCommand.CommandTimeoutがデフォルト値30秒で終了したとします。.net SqlCommandTimeOutと接続プール

これらのSQLコマンドの一部が長いクエリであると仮定し、タイムアウト例外が発生する可能性があります。

私が間違っている場合は、この例外はちょうど.Netはもう待ってはいけませんが、私たちが接続プールを使用している場合は、この接続が開いたままである可​​能性があります。 SQLサーバー側?または、接続プールを使用しているかどうかに関わらず、突然停止するようなシステム間に隠れた通信がいくつかありますか?

メカニズムが何であるかを知りたいだけで、SQLサーバーのパフォーマンスに影響します。クエリが実際に実行されている場合に実行するのに10分を要するなど、クエリが本当に長くても、誰も結果を得ることができないため、不必要なサーバーを遅らせるかもしれません。

UPDATE

だからここに私は、特に接続プールについて聞いてるのよ、それはコードが例外処理との接続を閉じますか、私たちは好ましいパターンであるコードを使用していると仮定できること間違いですここで@dashという名前です。問題は、そのSqlConnectionオブジェクトでClose()メソッドまたはDispose()メソッドを呼び出すと、接続プールに返され、物理的に閉じないことです。

プールに戻ったときに、SQL Server側でその長いクエリが実行されているかどうかを確認しています。可能であれば、それを避ける方法。データベーストランザクションについて、はいロールバックはそれを待つことになりますと、我々は、接続を閉じていないと、まだプールにそれを返すことを言及@dashため

UPDATEは再び

感謝。だから、それはちょうど長い選択クエリまたは更新プログラムですが、データベーストランザクションを一切伴わずに1つの個別の更新プログラムがあればどうでしょうか?具体的には、SQL Serverに結果を必要としないことを伝える方法があるかどうかを知りたいのですが、実行を停止してください。

+1

いいえ。方法はありません - SQL Server上で実行中のプロセスを強制終了できますが、実際にSQL Serverが実行していることを管理する必要があります。すべての場合と同様に、サーバーのパフォーマンスを低下させるクエリを実行することを選択した場合、それはあなたの選択です:-) – dash

+0

SQL KILLコマンドを使用してSQL Server上で実行中のプロセスを強制終了できます。 KILL SPIDを使用し、SPIDを取得するにはSELECT @@ SPIDを使用するか、sysテーブルのいずれかから現在のプロセスをすべて取得します。 –

答えて

5

すべては実際にどのようにクエリを実行しているかによって異なります。

は、次のクエリを想像:物事が起こるのだろう

SqlConnection myConnection = new SqlConnection("connection_string"); 

SqlCommand myCommand = new SqlCommand(); 
myCommand.Connection = myConnection; 
myCommand.CommandType = CommandType.StoredProcedure; 
myCommand.CommandTimeout = some_long_time; 
myCommand.CommandText = "database_killing_procedure_lol"; 

myConnection.Open() //Connection's now open 

myCommand.ExecuteNonQuery(); 

つを。このメソッドはcommand.ExecuteNonQuery()が終了するまでキューに入れられます。もう1つは、メソッドの実行中に接続プールから接続を引き継ぐことです。

タイムアウトするとどうなりますか?さて、例外がスローされます。つまり、Numberプロパティが-2のSqlExceptionです。ただし、上記のコードでは、例外管理はないので、オブジェクトは範囲外になり、オブジェクトが処分されるまで待つ必要があります。特に、私たちの接続はこれが起こるまで再利用できません。

それは以下のパターンが好まれる理由の一つだ:それは、すぐにクエリが完了すると、いずれかの自然に(それが完了するまで実行)、ということを意味

using(SqlConnection myConnection = new SqlConnection("connection_string")) 
{ 
    using(SqlCommand myCommand = new SqlCommand()) 
    { 

     SqlCommand myCommand = new SqlCommand(); 
     myCommand.Connection = myConnection; 
     myCommand.CommandType = CommandType.StoredProcedure; 
     myCommand.CommandTimeout = some_long_time; 
     myCommand.CommandText = "database_killing_procedure_lol"; 

     myConnection.Open() //Connection's now open 

     myCommand.ExecuteNonQuery();  

    } 

} 

または例外によって(タイムアウトまたはそれ以外の場合)、リソースはとすぐに返されます

特定の問題では、実行に時間がかかります多数のクエリを持つことは、多くの理由で悪いことです。 Webアプリケーションでは、限られた数のリソースに対して多数のユーザーが競合する可能性があります。メモリ、データベース接続、CPU時間などが含まれます。したがって、これらのいずれかを高価な操作で縛ると、Webアプリケーションの応答性とパフォーマンスが低下したり、同時に処理できるユーザー数が制限されたりします。さらに、データベース操作が高価な場合は、データベースを縛ることもできます。

この理由だけで、データベースクエリの実行時間を延ばそうとするのは、常に価値があります。できない場合は、同時に実行できるクエリの種類についていくつか注意する必要があります。

EDIT:

ですから、実際にSQL Serverの側で何が起こっているかに興味がある...答えは、それが依存...です! CommandTimeoutは実際にはクライアントイベントです。あなたが言っていることは、クエリがn秒以上かかると、それ以上待たずに済むということです。 SQL Serverはこれが当てはまると言われますが、現在実行中の処理を処理しなければならないため、SQL Serverがクエリを終了するまでに実際に時間がかかることがあります。これは優先順位をつけようとしますが、それはそれです。

これは特にトランザクションに当てはまります。トランザクションでラップされたクエリを実行していて、それを例外管理の一部としてロールバックしている場合は、ロールバックが完了するまで待つ必要があります。

人々がパニックを起こして、クエリが実行されているSQLプロセスIDに対してコマンドKILLを発行することも非常に一般的です。これは、コマンドがトランザクションを実行していると間違っていることがよくありますが、しばしばロング・ランニング・セレクトでは問題ありません。

SQL Serverは、一貫性を保つように状態を管理する必要があります。クライアントがもうリッスンしていないということは、無駄な作業をしたことを意味しますが、SQL Serverはそれ自身の後でクリーンアップする必要があります。

はい、ASP.Net側は気にしませんが、SQL Serverはまだ開始した作業を完了するか、その作業を安全に破棄できるポイントに到達する必要があります。開いたトランザクションの変更をロールバックします。

これは明らかに、クエリに応じてデータベースサーバーに影響を与える可能性があります。

トランザクションの外部で長時間実行されているSELECTまたはUPDATEまたはINSERTも終了する必要があります。 SQL Serverはできるだけ早くそれを試み、放棄しますが、それが安全である場合に限ります。明らかに、UPDATESとINSERTの場合、特にデータベースが一貫している点に到達する必要があります。 SELECTのためにできるだけ早く終了しようとします。

+0

私は私の質問についてはっきりしていません。申し訳ありませんが、接続プールについて質問していますが、「使用」キーワードを使用して練習していないため、更新された質問を確認してください。 –

+0

それは同じことです。接続が完了したら直ちに接続を解放しないと、接続プール内で再利用できるようになりません。この例では、予期せずに意図せずに接続を保持する方法を強調しています。最後の部分では、長時間実行されている多くのクエリを実行したときのパフォーマンスの問題について説明します。 – dash

+0

ちょっと私は私の質問を更新してください、私は本当に別の質問をしていることを確認してください、私は接続を閉じて接続プールに戻ります、それはまだSQLサーバー側で実行されます。私はどのように.Netが接続プールを処理するのか尋ねていません。ありがとう –

0

データベーストランザクションについて、はい ロールバックはそれを待つことになりますと、我々は、接続を閉じていないと、まだプールにそれを返す ことを言及@dashいただきありがとうございます。だから、それはちょうど長い選択クエリまたは 更新が、データベースなしで1つの個別の更新 トランザクションが関与している場合はどうなりますか?そして具体的には私はそこに方法があることを知りたいです 私は結果を必要としないことをSQL Serverに伝えることができます 実行を停止しますか?私は、このリンクは答えるだろうと思い

は、あなたが探している待つことも Link1 Link2

+0

「SqlCommandの実行をキャンセルしようとしています」という覚えがあります。恐れている。 – dash