12

一般的なタイプの質問があります。SQL Server ストアド プロシージャを呼び出す C# アプリケーションがあり、C# アプリケーションがタイムアウトした場合、サーバー上のプロシージャ コールは最後まで実行されますか?

4

5 に答える 5

4

いいえ。以下は複製です。タイムアウトが発生すると、実行中のプロセスが強制終了され、すぐに停止します。トランザクションが指定されていない場合、タイムアウト前にストアド プロシージャで実行された作業は永続化されます。同様に、サーバーへの接続が外力によって切断された場合、SQL Server は実行中のプロセスを強制終了します。

using (var conn = new SqlConnection(@"Data Source=.;Initial Catalog=Test;Integrated Security=True"))
{
    conn.Open();

    using (var setupTable = new SqlCommand(@"
        IF NOT EXISTS (
            SELECT *
            FROM
                sys.schemas s
                    INNER JOIN sys.tables t ON
                        t.[schema_id] = s.[schema_id]
            WHERE
                s.name = 'dbo' AND
                T.name = 'TimeoutTest')
        BEGIN
            CREATE TABLE dbo.TimeoutTest
            (
                ID int IDENTITY(1,1) PRIMARY KEY,
                CreateDate datetime DEFAULT(getdate())
            );
        END

        -- remove any rows from previous runs
        TRUNCATE TABLE dbo.TimeoutTest;", conn))
    {
        setupTable.ExecuteNonQuery();
    }

    using (var checkProcExists = new SqlCommand(@"
        SELECT COUNT(*)
        FROM
            sys.schemas s
                INNER JOIN sys.procedures p ON
                    p.[schema_id] = s.[schema_id]
        WHERE
            s.name = 'dbo' AND
            p.name = 'AddTimeoutTestRows';", conn))
    {
        bool procExists = ((int)checkProcExists.ExecuteScalar()) == 1;

        if (!procExists)
        {
            using (var setupProc = new SqlCommand(@"
                CREATE PROC dbo.AddTimeoutTestRows
                AS
                BEGIN

                    DECLARE @stop_time datetime;

                    SET @stop_time = DATEADD(minute, 1, getdate());

                    WHILE getdate() < @stop_time
                    BEGIN
                        INSERT INTO dbo.TimeoutTest DEFAULT VALUES;

                        -- wait 10 seconds between inserts
                        WAITFOR DELAY '0:00:10';
                    END

                END", conn))
            {
                setupProc.ExecuteNonQuery();
            }
        }
    }

    bool commandTimedOut = false;

    try
    {
        using (var longExecution = new SqlCommand("EXEC dbo.AddTimeoutTestRows;", conn))
        {
            // The time in seconds to wait for the command to execute.
            // Explicitly setting the timeout to 30 seconds for clarity.
            longExecution.CommandTimeout = 30;

            longExecution.ExecuteNonQuery();
        }
    }
    catch (SqlException ex)
    {
        if (ex.Message.Contains("Timeout"))
        {
            commandTimedOut = true;
        }
        else
        {
            throw;
        }
    }

    Console.WriteLine(commandTimedOut.ToString());

    // Wait for an extra 30 seconds to let any execution on the server add more rows.
    Thread.Sleep(30000);

    using (var checkTableCount = new SqlCommand(@"
        SELECT COUNT(*)
        FROM
            dbo.TimeoutTest t;", conn))
    {
        // Only expecting 3, but should be 6 if server continued on without us.
        int rowCount = (int)checkTableCount.ExecuteScalar();

        Console.WriteLine(rowCount.ToString("#,##0"));
    }
}

Console.ReadLine();

次の出力を生成します

True
3

Management Studio からストアド プロシージャを実行すると、1 分間で 6 行が追加されます。

于 2016-04-21T21:46:32.760 に答える
2

簡単な答えは「はい」です....ここに私の主張を裏付ける情報があります

アプリケーションが「タイムアウト」する可能性がある場所は実際にはいくつかありますが、その 1 つはコマンド実行のタイムアウトです ...

コマンド実行タイムアウト- このプロパティは、コマンドの実行中または結果の処理中のすべてのネットワーク読み取りの累積タイムアウトです。最初の行が返された後もタイムアウトが発生する可能性があり、ユーザーの処理時間は含まれず、ネットワークの読み取り時間のみが含まれます。

タイムアウトした場合、コマンドはそれ自体でロールバックしません。タイムアウトした場合、コードの周りにトランザクションが必要になります。

行が返されるときにタイムアウトが発生する可能性がある場合は、C# が SQL Server にコマンドの実行を停止するように指示しないということよりも、いつでもタイムアウトが発生する可能性があることを意味します。コマンドをトランザクションにラップするなど、それについて行うことができます

ソース: https://blogs.msdn.microsoft.com/mattn/2008/08/29/sqlclient-timeouts-revealed/ ... そして経験

于 2016-04-21T14:56:19.570 に答える
0

それについての私の考えは、すべてはプロシージャーの呼び出しによって開かれた接続に関するものだということです。コードが using ブロック内で実行された場合、またはガベージ コレクションが行われた場合、SP の実行はロールバックされると思います。

于 2016-04-21T15:33:37.150 に答える
0

SQlCommand クラスを使用している場合、アプリがタイムアウトすると、クエリの実行がロールバックされます。

于 2016-04-21T14:47:07.930 に答える