🎃

SqlConnection.ConnectionTimeout と SqlCommand.CommandTimeout の違い

2022/12/19に公開

SqlConnection.ConnectionTimeoutSqlCommand.CommandTimeout の違いをいまいち理解していなかったので、調べてみた。

結論

SqlConnection.ConnectionTimeout は DB への接続を待機する時間。
デフォルト値は 15 秒。

SqlCommand.CommandTimeout はクエリの実行を待機する時間。
デフォルト値は 30 秒。

検証環境

name version
C# 10.0
.NET 6.0.11
SQL Server 15.0.4261.1

接続タイムアウトの検証

わざと間違った DataSource を指定してみる。

var connectionString = new SqlConnectionStringBuilder
{
    DataSource = "local", // 誤ったDataSource
    InitialCatalog = "test",
    UserID = "sa",
    Password = "rootRootr00t",
    ConnectTimeout = 10, // 10秒待機
}.ToString();

try
{
    using (var connection = new SqlConnection(connectionString))
    {
        var query = "WAITFOR DELAY '00:00:10'";

        using (var command = new SqlCommand(query, connection))
        {
            command.Connection.Open();

            // 10秒待機
            command.CommandTimeout = 10;

            command.ExecuteNonQuery();
        }
    }

    Console.WriteLine("完了");
}
catch (Exception exception)
{
    Console.WriteLine("例外発生");
    Console.WriteLine(exception.Message);
}

実行結果

10 秒経っても DB に接続できなかったので、例外が発生し、下記メッセージが出力された。

例外発生
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

クエリタイムアウトの検証

CommandTimeout を 5 秒に設定し、10 秒待機するクエリを実行する。

var connectionString = new SqlConnectionStringBuilder
{
    DataSource = "localhost",
    InitialCatalog = "test",
    UserID = "sa",
    Password = "rootRootr00t",
    ConnectTimeout = 10,
}.ToString();

try
{
    using (var connection = new SqlConnection(connectionString))
    {
        // 10秒待機するクエリ
        var query = "WAITFOR DELAY '00:00:10'";

        using (var command = new SqlCommand(query, connection))
        {
            command.Connection.Open();

            // 5秒待機
            command.CommandTimeout = 5;

            command.ExecuteNonQuery();
        }
    }

    Console.WriteLine("完了");
}
catch (Exception exception)
{
    Console.WriteLine("例外発生");
    Console.WriteLine(exception.Message);
}

実行結果

クエリを実行してから 5 秒経っても DB からの応答がなかったためタイムアウトとなり、下記メッセージが出力された。

例外発生
Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
Operation cancelled by user.

参考

SqlConnectionStringBuilder.ConnectTimeout プロパティ (System.Data.SqlClient) | Microsoft Learn
SqlConnection.ConnectionTimeout プロパティ (System.Data.SqlClient) | Microsoft Learn
SqlCommand.CommandTimeout プロパティ (System.Data.SqlClient) | Microsoft Learn

GitHubで編集を提案

Discussion