SQLServerタイムアウト例外をキャッチする方法


117

SQLサーバーのタイムアウト例外を個別にキャッチして、異なる方法で処理できるようにする必要があります。SqlExceptionをキャッチし、メッセージ文字列に「タイムアウト」が含まれているかどうかを確認できることはわかっていますが、それを行うより良い方法があるかどうか疑問に思っていましたか?

try
{
    //some code
}
catch (SqlException ex)
{

    if (ex.Message.Contains("Timeout"))
    {
         //handle timeout
    }
    else
    {
         throw;
    }
}

ConnectionTimeoutまたはCommandTimeoutを探していますか?つまり、接続が失敗するか、実行されたコマンドが失敗することを期待していますか?
edosoft 2008

CommandTimeoutを探しています。これは、デフォルトの30秒に設定されていると思います
brodie

回答:


157

タイムアウトを確認するには、ex.Numberの値を確認すると思います。-2の場合は、タイムアウトの状況です。

-2は、タイムアウトのエラーコードで、SQL ServerのMDACドライバであるDBNETLIBから返されます。これは、Reflectorをダウンロードし、System.Data.SqlClient.TdsEnumsでTIMEOUT_EXPIREDを探すことで確認できます。

あなたのコードは次のようになります:

if (ex.Number == -2)
{
     //handle timeout
}

失敗を示すコード:

try
{
    SqlConnection sql = new SqlConnection(@"Network Library=DBMSSOCN;Data Source=YourServer,1433;Initial Catalog=YourDB;Integrated Security=SSPI;");
    sql.Open();

    SqlCommand cmd = sql.CreateCommand();
    cmd.CommandText = "DECLARE @i int WHILE EXISTS (SELECT 1 from sysobjects) BEGIN SELECT @i = 1 END";
    cmd.ExecuteNonQuery(); // This line will timeout.

    cmd.Dispose();
    sql.Close();
}
catch (SqlException ex)
{
    if (ex.Number == -2) {
        Console.WriteLine ("Timeout occurred");
    }
}

はい、それは私が現在やっていることのほとんどですが、-2のチェックはあまりエレガントではありません
brodie

12
Red Gateのリフレクターをダウンロードして、TIMEOUT_EXPIREDを検索します。これはSystem.Data.SqlClient.TdsEnumsにあり、その値は-2です。:o)
ジョナサン

2
Reflectorにアクセスできない人のために:リンク
ankitk 2013年

4
@brodieそのため、定数を作成する必要があり、定数のコメントで「マジック」値がどこから来たかを説明できます。
Jason L.

18

ここ:http : //www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html

また、Thomas Weingartnerが書いた次の記事も読むことができます。

タイムアウト:SqlException.Number == -2(これはADO.NETエラーコードです)
一般的なネットワークエラー:SqlException.Number == 11
デッドロック:SqlException.Number == 1205(これはSQL Serverエラーコードです)

...

「一般的なネットワークエラー」もタイムアウト例外として処理します。これはまれな状況でのみ発生します。たとえば、更新/挿入/削除クエリが長時間実行トリガーを発生させる場合などです。


6

c#6用に更新:

    try
    {
        // some code
    }
    catch (SqlException ex) when (ex.Number == -2)  // -2 is a sql timeout
    {
        // handle timeout
    }

とてもシンプルで見やすい!!


0

SqlException.ErrorCodeプロパティの値は?それで作業できますか?

タイムアウトがある場合、-2146232060のコードをチェックする価値があるかもしれません。

これをデータコードの静的constとして設定します。


2
ErrorCodeのドキュメントを見ると、Interopレベルのエラーが報告されているようです。したがって、COMエラーのレベルの方が多いか、プロバイダーが、実行していることに関連する特定のエラーではなく、(一般に)例外を検出した可能性があります。
Eric Tuttleman、

@Ericは正しい-これはSqlException型のHRESULTコードであり、例外のソースではありません。
codekaizen

0

わかりませんが、実行タイムアウトまたはコマンドタイムアウトが発生した場合、クライアントはSQL Serverに「ABORT」を送信し、クエリ処理を単に破棄します。トランザクションはロールバックされず、ロックは解放されません。この問題を解決するには、ストアドプロシージャでトランザクションを削除し、.NetコードでSQLトランザクションを使用してsqlExceptionを管理します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.