0

Stored를 호출하여 병렬 스레드의 두 SQL Server 테이블에서 CRUD를 수행하는 동안 위에서 언급 한 데드락 예외가 발생했습니다. 절차는 다음과 같습니다.SQL Azure - 트랜잭션 (프로세스 ID 160)이 다른 프로세스의 잠금 리소스에서 교착 상태에 있었고 교착 상태 피해자로 선택되었습니다.

우리는 코드 블록을 100-150 병렬 스레드로 돌리는 데스크톱 응용 프로그램을 가지고 있으며, 코드 블록은 SQL Bulk Copy을 사용하여 TableA에 삽입하고 3 개의 저장 프로 시저를 호출합니다. 저장 프로시 저는 TableA의 일부 선택에 따라 TableB에서 삽입, 업데이트 및 삭제를 수행합니다.

응용 프로그램이 스레드 실행을 시작하자마자 SQL Server는 스레드 수가 일정하게 실행되는 동안 특정 스레드 수에 대해 언급 된 데드락 예외를 던지기 시작합니다.

예외 메시지 : 트랜잭션 (프로세스 ID 160)이 다른 프로세스에서 잠금 리소스에 교착 상태가 발생하여 교착 상태 희생자로 선택되었습니다. 트랜잭션을 재실행하십시오.

이와 관련하여 도움이 될 것입니다.

감사합니다.

답변

0

트랜잭션 (프로세스 ID 160)이 다른 프로세스의 잠금 리소스에서 교착 상태임을 분명하게 보여주는 메시지입니다. 잠금 수준은 서로 다를 수 있습니다. 다른 스레드가 해당 특정 자원을 잠그기 전에 잠금이 해제되지 않습니다. 프로세스 ID를 삭제하고 잠금 충돌이있는 경우 워크 플로를 확인하십시오.

+0

예, 병렬 실행 때문에 같은 개체 (두 테이블 중 하나)에 액세스하는 데 충돌이 있지만 여러 스레드가 동시에 같은 테이블에 액세스 할 수 있도록 데드락을 피하는 방법은 무엇입니까? 데이터베이스 수준 또는 저장 프로 시저 수준에 대한 특정 설정이 있습니까? –

+0

같은 순서로 개체에 액세스하십시오. 트랜잭션을 짧고 한 번에 처리하십시오. 낮은 격리 수준을 사용하십시오. 행 버전 관리 기반 격리 수준을 사용하십시오. ... 바운드 연결을 사용하십시오. –

2

이 SQL Server 또는 SQL Azure/Azure SQL DB입니까? "상자"SQL Server 인 경우 ALTER DATABASE SET READ_COMMITTED_SNAPSHOT ON을 고려할 수 있습니다. 그러면 읽기 버전이 활성화됩니다. 이 상태에서 여전히 교착 상태가 발생할 수는 있지만, 얻을 가능성이있는만큼 은총에 가깝습니다.

읽기 버전 그래서 먼저 읽어하고 비즈니스 로직과 호환 있는지 확인하십시오, 미묘한 방법으로 동시성 모델을 변경 : 그렇지 않으면 https://msdn.microsoft.com/en-us/library/tcbchxcb(v=vs.110).aspx

, 트랜잭션 범위 최소화에 대한 Srivats의 다른 제안은 항상하지 않습니다 구현하기 쉽지만 여전히 견고합니다. 이 목록에 다음을 추가합니다. 인덱스 된 쿼리 액세스 경로가 있는지 확인하고 트랜잭션 내의 쿼리 중 전체 테이블 또는 인덱스 스캔이 필요하지 않은지 확인합니다.

+0

이것은 SQL Azure 데이터베이스입니다. 가이드 라인을 주셔서 감사합니다. 우리는 이미 데이터베이스 수준 격리와 트랜잭션 수준 격리를 모두 시도했지만 아무 것도 작동하지 않습니다. –

+0

스냅 샷 격리를 활성화하면 내 문제가 해결되었습니다. 고맙습니다! @ KamalHaider 나는 또한 나의 선택 조항에 "(nolock)"이있다. 희망이 당신을 돕는다! – Bruce

관련 문제