2010-06-05 5 views
1

SQL Server 2008 Enterprise를 사용하고 있습니다. 같은 시간에 여러 스레드에 의해 실행되는 경우 왜이 저장 프로 시저의 단일 삭제 문이 교착 상태를 일으키는 지 궁금합니다.단일 SQL 삭제 명령문으로 인해 교착 상태가 발생하는 이유는 무엇입니까?

Delete 문에서 Param1은 FooTable 테이블의 열이고 Param1은 다른 테이블의 외부 키입니다 (다른 테이블의 다른 기본 키 클러스터형 인덱스 열을 참조 함). 테이블 FooTable에 대한 Param1 자체에는 색인이 없습니다. FooTable에는 클러스터 된 기본 키로 사용되지만 Param1 열로는 사용되지 않는 다른 열이 있습니다. 사전에

create PROCEDURE [dbo].[FooProc]  
( 
@Param1 int 
,@Param2 int 
,@Param3 int 
)  
AS  

DELETE FooTable WHERE Param1 = @Param1  

INSERT INTO FooTable  
( 
Param1 
,Param2 
,Param3 
)  
VALUES  
( 
@Param1 
,@Param2 
,@Param3 
)  

DECLARE @ID bigint  
SET @ID = ISNULL(@@Identity,-1)  
IF @ID > 0  
BEGIN  
     SELECT IdentityStr FROM FooTable WHERE ID = @ID 
END 

덕분에, 조지

+2

교착 상태 그래프를 캡처하여 게시물에 추가하십시오. 그때까지는 우리 모두가 추측하고 있습니다. 교착 상태 그래프를 포착하는 방법은 http://msdn.microsoft.com/en-us/library/ms190465.aspx를 참조하십시오. –

+0

안녕하세요 Remus, 교착 상태를 시작하는 방법? 스트레스 테스트를 수행하는 도구 또는 샘플 코드 – George2

+1

프로 시저를 살펴보면 Param1을 기반으로 모든 행을 삭제 한 다음 단 하나의 행만 삽입한다는 것을 알았습니다. UPDATE 문을 사용할 수 없습니까? – ZippyV

답변

1

일반적인 답 : 그것은 달려! :-)

시스템의 트래픽 양 및 사용중인 트랜잭션 격리 수준.

격리 수준은 데이터를받는 방법과 잠금이 진행되는 정도를 제어합니다. 트랜잭션 격리 수준에 대해 들어 본 적이없는 경우 기본값 인 READ COMMITTED를 사용하고 있습니다. 이는 너무 나쁜 선택이 아니어야합니다.

그러나 어떤 이유로 든 SERIALIZABLE과 같은 것을 사용하려는 경우 교착 상태가 아닌 지연이 발생할 수 있습니다. 한 트랜잭션이 완료 될 때까지 일정 기간 동안 테이블이 잠길 수 있습니다. 모든 작업이이 순서 (첫 번째 삭제, 삽입, 선택) 순서대로 작동하면 교착 상태가 발생하는 방법을 알 수 없습니다.

www.sql-server-performance.com에서 SQL 트랜잭션 격리 수준을 읽으십시오.

+1

필자는 @ George2의 이전 교착 상태 스레드에 대해 주장했다. 교착 상태는 병렬 실행 계획과 페이지 잠금을 "오른쪽"순서로 할당하면 두 개의 동시 삭제 사이에서 발생할 수있다. 그러나 나는 방금 테스트에서이 교착 상태가 발생하도록 만들려고 노력했다. 나는 더 이상 그것을 미룰 수있는 시간을 갖지 못했다. –

+0

안녕하세요 마크, 교착 상태 시나리오를 재현하는 데 사용할 수있는 도구 또는 샘플 코드가 있습니까? – George2

+0

안녕 마틴, 왜 내 장면이 교착 상태에 빠졌는지 아는 사람이 있습니까? 교착 상태 시나리오를 재현하는 데 사용할 수있는 도구 또는 샘플 코드 – George2

2

나는 동시성 경험이없는하지만 (그리고 어쩌면 당신의 교착 상태를 고정) 변경됩니다 프로 시저의 2 가지가 있습니다 :

  • 전체 프로 시저를 트랜잭션으로 랩핑하십시오. 이것은 FooProc 1이 이라고 불리는 것을 막기 위해서이며, FooProc 2가 동일한 @ Param1을 모두 가지고있는 DELETE 문장을 실행하는 동안 SELECT 문을 실행하려고합니다.
  • @@ Identity를 사용하지 말고 대신 SCOPE_IDENTITY을 사용하십시오.
  • 에 대한

    Interesting link

은 @@ IDENT_CURRENT 대 SCOPE_IDENTITY 대 정체성()()

+0

ZippyV에게 감사드립니다. 내 장면이 교착 상태에있는 이유는 무엇입니까? 교착 상태 시나리오를 재현하는 데 사용할 수있는 도구 또는 샘플 코드 – George2

+1

http://www.mssqltips.com/tip.asp?tip=1036 – ZippyV

+0

Table FooTable이 큰 경우 내 시나리오가 교착 상태를 유발할 것으로 생각합니까? – George2

0

큰 테이블 BarTable에 FooTable을 참조하는 외래 키 제약 조건이있는 경우 FooTable에서 하나의 단일 행을 삭제하면 해당 행에 대한 참조를 위해 모든 BarTable 행을 검사해야합니다.

뿐만 아니라이 엄청나게 느린, 그것은 악화입니다 :이 검사를하는 동안, FooTable에서 두 개의 단일 행의 두 개의 동시 삭제가 BarTable의 기본 키에 교착 얻을 수있는

을 사용하여 인덱스를 작성하는 경우 (!) FooTable을 참조하는 열에 대한 BarTable에서 삭제를 사용하면 해당 색인을 사용하여 작업 속도를 크게 높일 수 있습니다. 그래서

:

당신의 외래 키 제약 조건이 인덱스에 의해 백업되어 있는지 확인합니다.

관련 문제