1. ホーム
  2. .net

[解決済み] デッドロックで発生したSqlExceptionをキャッチするには?

2023-01-15 05:23:17

質問

.NET 3.5 / C#のアプリから、以下のようにキャッチしたい。 SqlException をキャッチしたいのですが デッドロックが原因の場合のみ を SQL Server 2008 インスタンス上で実行する必要があります。

典型的なエラーメッセージは Transaction (Process ID 58) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

それでも、文書化されていないようです。 エラーコード は存在しないようです。

の存在に対する例外のフィルタリング デッドロック キーワードの存在に対して例外をフィルタリングすることは、この動作を実現するための非常に醜い方法のように思えます。誰かこれを行う正しい方法を知っていますか?

どのように解決するのですか?

デッドロックに対する Microsft SQL Server 固有のエラーコードは 1205 なので、SqlException を処理し、それをチェックする必要があります。そのため、例えば、他のすべてのタイプのSqlExceptionに対して、例外をバブル化したい場合。

catch (SqlException ex)
{
    if (ex.Number == 1205)
    {
        // Deadlock 
    }
    else
        throw;
}

または、C# 6で利用可能な例外フィルタリングを使用します。

catch (SqlException ex) when (ex.Number == 1205)
{
    // Deadlock 
}

与えられたメッセージに対する実際の SQL エラーコードを見つけるために便利なことは、SQL Server の sys.messages を見ることです。

SELECT * FROM sys.messages WHERE text LIKE '%deadlock%' AND language_id=1033

デッドロックを処理する別の方法(SQL Server 2005以降)は、TRY...CATCHサポートを使用してストアドプロシージャ内で処理することです。

BEGIN TRY
    -- some sql statements
END TRY
BEGIN CATCH
    IF (ERROR_NUMBER() = 1205)
        -- is a deadlock
    ELSE
        -- is not a deadlock
END CATCH

完全な例があります はこちら に、デッドロック再試行ロジックを純粋に SQL 内に実装する方法の完全な例があります。