現在のアプリケーションでは、T-SQL Update コマンドを呼び出して更新を実行しています。問題は、同じレコードがその時点で他のユーザーによってロックされている場合です。
.NET アプリケーションでは、アプリケーションは SQL Server タイムアウトまで待機し、その後 SqlException タイムアウトをスローします。
例外をキャッチするのではなく、特定のレコードが他のプロセスによってロックされているかどうかを最初にチェックすることは可能ですか?
現在のアプリケーションでは、T-SQL Update コマンドを呼び出して更新を実行しています。問題は、同じレコードがその時点で他のユーザーによってロックされている場合です。
.NET アプリケーションでは、アプリケーションは SQL Server タイムアウトまで待機し、その後 SqlException タイムアウトをスローします。
例外をキャッチするのではなく、特定のレコードが他のプロセスによってロックされているかどうかを最初にチェックすることは可能ですか?
いいえ、そうではありません。
標準的な方法は、Number (デッドロックの犠牲者)を使用try/catch
して処理し、クエリを再試行することです。SqlException
1205
try
{
// do stuff...
}
catch (SqlException sqlEx)
{
switch (sqlEx.Number)
{
case -2: // Client Timeout
case 701: // Out of Memory
case 1204: // Lock Issue
case 1205: // >>> Deadlock Victim
// handle deadlock
break;
case 1222: // Lock Request Timeout
case 2627: // Primary Key Violation
case 8645: // Timeout waiting for memory resource
case 8651: // Low memory condition
...
}
}
[注: 簡潔にするために break ステートメントは追加されていません
また、適切なカバリング インデックスを提供することで、多くのロックの問題を解消できることにも注意してください。
非常に短いタイムアウトで別の接続を使用して、フィールドを更新してレコードをロックしようとすることもできますが、それでも 100% の信頼性は得られません。
複数のユーザーが同じレコードを編集している状況が実際にある場合は、楽観的ロック手法を検討する必要があります。
また、ユーザーがレコードをロックすることをまったく許可していないことを確認してください。更新には切断モードを使用してください。つまり、ロックは更新の短い時間 (<100 ms) だけ発生します。