2012-05-03 5 views
2

우선 SQL Server 2005에서 교착 상태가 실제로 발생하는 근본 원인을 알고 싶습니다. 두 프로세스가 테이블의 같은 행에 액세스 할 때가 그 때문입니까?SQL Server 2005에서 교착 상태를 제거하는 방법은 무엇입니까?

어쨌든, 두 테이블 모두 동일한 구조를 갖는 두 개의 테이블 _Table_Now__Table_History_을 고려하십시오.

NAME이라는 열이 있다고 가정합니다.

그래서 하나 개의 프로세스가 _Table_Now_NAME='BLUE'와 레코드를 업데이트하려고 할 때, 먼저, 그 다음 _Table_History_에서 이전에 현재의 행을 삭제 또한 _Table_Now_를 업데이트하고 _Table_History_NAME='BLUE'하여 본 행을 넣어해야합니다.

삭제하는 동안 교착 상태가 발생합니다. 왜 그런지 모르겠다 고요?

나를 안내하십시오! A는

을 완료하면 B가 완료되고 B는 \ 계속 시작됩니다 때 그냥 \ 시작 계속 있도록 프로세스 A가 프로세스 B와 프로세스 B에 의존 할 때 교착 상태가 기본적으로 의미

+2

교착 상태는 일반적으로 여러 동시 트랜잭션을 포함합니다. 하나의 거래를 설명했습니다. 교착 상태에 관련된 다른 트랜잭션은 무엇입니까? – NPE

+1

좋은 연습은'with (NOLOCK)'및'with (ROWLOCK) '와 같은 쿼리마다 힌트를 제공하여 dead lock을 피하는 것입니다. lock을 제거하려면'kill N'을 사용하여 spids 중 하나를 죽일 수 있습니다. 여기서 n은 spid입니다. 이드는 다른 쪽이 계속되는 것을 허용 할 것입니다. – AbstractChaos

+0

더 이상의 정보가 없으면 도움이 될 것입니다. 다음은 SQL 프로파일 러를 사용하여 교착 상태를 분석하는 방법에 대한 링크입니다. http://msdn.microsoft.com/en-us/library/ms188246.aspx –

답변

1

는, 프로세스 A의 의존이 무엇인지 테이블 (또는 행) 잠금이 발생했을 수 있으므로 SQL은 테이블을 업데이트하기 전에 행을 잠급하여 업데이트를 수행하는 동안 다른 프로세스가 해당 행에 액세스하지 못하도록합니다.

어떻게하면 insert \ update \ delete를 더 잘 수행 할 수 있습니까? 이 시나리오에서는 교착 상태가 발생하지 않아야합니다.

참고로 with (NOLOCK)을 사용하지 마십시오. 예를 통해 잠금을 방지하지만 SQL Server에 커밋되지 않은 데이터를 읽도록 지시함으로써 데이터 불일치가 발생할 수 있습니다.

+0

이것이 내 이유입니다. 정상적인 상황에서는 데드 록이 없어야합니다. 심지어 새 쿼리 창을 열고 SELECT * FROM _Table_History_ NAME = 'BLUE'와 같은 간단한 select 쿼리를 작성할 때 ...이 문을 몇 번 실행하면 데드락이 표시됩니다. – JackAss

+1

교착 상태가 발생하는 방식에 대한 자세한 정보를 제공 할 수 있습니까? – Diego

+0

Ok. 전 SQL Server 2005를 사용하고 있습니다. 이제 SQL Server 2005에서 일부 연결이 실행되고 일부는 실행되지만 일부는 일시 중단됩니다. SUSPENDED 연결 수가 증가하면 응용 프로그램이 다운됩니다. sp_who2를 실행했습니다. – JackAss

0

프로세스 A가 프로세스 B가 리소스를 릴리스 할 때까지 대기하고 프로세스 B가 프로세스 A가 리소스를 릴리스 할 때까지 대기 중일 때 교착 상태가 발생합니다.
1. 삭제 4 Table_Now

3. 업데이트를 Table_History에 Table_Now의 행을 행을
2 업데이트를 행을 읽기 : 내가 제대로 업데이트의 순서를 이해한다면

, 그것은 이것이다 행을 Table_History.

트랜잭션 또는 잠금을 잘못 사용하면 위험한 순서가 될 수 있습니다. 교착 상태를 방지하기 위해

, 각 프로세스에 대해 당신은 실행해야합니다
1.
2. 어떤 문제가 발생
3. 경우 트랜잭션을 커밋 (또는 롤백 모든 DB 작업을 수행 트랜잭션 (바람직 테이블 잠금을) 시작 반면 DB 업데이트)

이렇게하면 두 프로세스 모두 테이블을 잠그고 모든 작업을 수행 한 다음 종료 할 수 있습니다.

이미 거래를 사용중인 경우 어떤 범위와 수준을 사용하고 있습니까? 그렇지 않다면 거래를 소개하십시오. 문제를 해결해야합니다.

+1

설명 된 시나리오에서 트랜잭션은 교착 상태를 만드는 확실한 방법입니다 :) 일반적으로 1 단계에서 (updlock) 힌트를 사용하여이를 피할 수 있습니다 - Table_Now를 읽으십시오. – Arvo

+0

이유는 위의 사용하지 않았다. 위의 경우 아무도 작동하지 않으면 들어오는 레코드를 잃을 것입니다. 삭제가 실패했다고 가정하십시오. 롤백하면 모든 것이 되돌려집니다. _Table_Now_에 삽입하는 것은 매우 높은 우선 순위입니다 – JackAss