교착 상태로 인한 SqlException을 잡는 방법은 무엇입니까?
닷넷 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
여기 MSDN에는 순수하게 SQL 내에서 교착 상태 재시도 논리를 구현하는 방법에 대한 전체 예제가 있습니다 .
교착 상태를 감지하고 실패한 작업을 다시 시도 할 수 있기를 원하기 때문에 약간의 문제에 대해 경고하고 싶습니다. 여기서 주제에서 약간 벗어난 것에 대해 실례합니다.
데이터베이스에서 감지 된 교착 상태는 연결이 .NET에서 열린 상태로 유지되는 동안 실행중인 트랜잭션 (있는 경우)을 효과적으로 롤백합니다. 동일한 연결에서 해당 작업을 재 시도하면 트랜잭션이없는 컨텍스트에서 실행되고 이로 인해 데이터가 손상 될 수 있습니다.
이것을 인식하는 것이 중요합니다. SQL로 인한 실패의 경우 완전한 연결을 고려하는 것이 가장 좋습니다. 작업 재 시도는 트랜잭션이 정의 된 수준에서만 수행 할 수 있습니다 (해당 트랜잭션과 연결을 다시 생성하여).
따라서 실패한 작업을 다시 시도 할 때 완전히 새로운 연결을 열고 새 트랜잭션을 시작했는지 확인하십시오.
다음은 교착 상태를 감지하는 C # 6 방법입니다.
try
{
//todo: Execute SQL.
//IMPORTANT, if you used Connection.BeginTransaction(), this try..catch must surround that code. You must rollback the original transaction, then recreate it and re-run all the code.
}
catch (SqlException ex) when (ex.Number == 1205)
{
//todo: Retry SQL
}
Make sure this try..catch surrounds your entire transaction. According to @Steven (see his answer for details), when the sql command fails due to the deadlock, it causes the transaction to be rolled back and, if you don't recreate the transaction, your retry will execute outside of the context of the transaction and can result in data inconsistencies.
참고URL : https://stackoverflow.com/questions/2256939/how-to-catch-sqlexception-caused-by-deadlock
'Programing' 카테고리의 다른 글
Python을 사용하여 네이티브 iPhone 앱을 작성할 수 있습니까? (0) | 2020.09.13 |
---|---|
C에서 enum 유형의 변수를 문자열로 사용하는 쉬운 방법은 무엇입니까? (0) | 2020.09.13 |
콘솔 애플리케이션 C #의 App.Config 파일 (0) | 2020.09.13 |
작동하는 GitLab 설치의 URL을 어떻게 변경합니까? (0) | 2020.09.13 |
Webstorm : "디렉터리를 확인할 수 없음" (0) | 2020.09.13 |