2015-01-01 3 views
0

SQL Server에서 "교착 상태 희생자"로 선택되는 응용 프로그램이 있습니다. 쿼리 아래에서 실행하려고하는 여러 스레드가 있습니다.SQL Server 데드락 다이어그램 이해

쿼리

merge Table_X as target 
using (values ('14410')) as source (CUST_ID) on target.CUST_ID = '14410' 
when matched then 
    update 
     SET CUST_NAME = 'xyz', CLOSE_DATE = NULL, 
      xx = 2, COMPLETE = 'No', 
      qwert = CASE WHEN qwert is null and 'Low' = 'High' THEN getDate() ELSE null END, 
      ACTIVE = 1, xcount = '913af80db3f424e34a9055e0ea9bc391' 

when not matched then 
    INSERT (CUST_ID, CUST_NAME, OPEN_DATE, CLOSE_DATE, xx, COMPLETE, qwert, ddd, ACTIVE, xcount) 
    VALUES ('14410', 'U.S. Robotics and Mechanical Men', '2007-08-31 15:14:23.0', NULL, 2, 'No', NULL, 0, 1, '913af80db3f424e34a9055e0ea9bc391') ; 

DECLARE @54229 numeric(19,0) 
SET @54229 = (SELECT id from Table_X where CUST_ID = '14410') 

insert into Table_Y (xyz, abc, ax, ay, az, bx, bxz, bz, UPDATED, abcd) 
    select 
     xyz, abc, ax, ay, az, bx, bxz, bz, UPDATED, abcd 
    from 
     Table_Z 
    where 
     abcd = @54229 

merge Table_Z as target 
using (values (@54229)) as source (abcd) on target.abcd = @54229 
when matched then 
    UPDATE 
     SET xyz = 1.1, abc = 1.1, ax = 1.1, ay = 1.1, az = 1.1, 
      bx = 1.1, bxz = 'Low', bz = 1.1, UPDATED = getdate() 

when not matched then 
    INSERT (xyz, abc, ax, ay, az, IS_FORCE_EDD, bx, bxz, bz, UPDATED, abcd) 
    VALUES(1.1, 1.1, 1.1, 1.1, 1.1, 0, 1.1,'Low', 1.1, getdate(), @54229); 

INSERT INTO Table_A(ACTION, DATE_TIME, PROFILE_ID, USER_ID) 
VALUES('Profile Change', getdate(), @54229, 1) 

Deadlock diagram

사람이 교착 상태 다이어그램을 설명 할 수 있습니까?

이 교착 상태를 예방하는 해결책을 제공해주십시오.

여러 항목을 읽고 with (nolock), isolation level을 시도했지만 적절한 해결책이 없습니다.

교착 상태가 발생하면 피해야 할 인덱스가 있습니까?

+0

종료가 느린 경우에도 교착 상태 메시지가 나타날 수 있습니다. 쿼리 성능을 향상 시키십시오. – Hogan

+0

@Hogan 데드락 오류는 실제 교착 상태가 감지 된 경우에만 발생합니다. –

+0

@MartinSmith - 교착 상태를 감지하는 것이 가능하지 않다고 생각합니다. 휴리스틱이 사용되고 휴리스틱은 리소스를 잠그고 해제하는 "느린"프로세스의 경우 "거짓 긍정"을 줄 수 있다고 생각합니다. . – Hogan

답변

1

클러스터되지 않은 인덱스 을 작성한 후 교착 상태 희생자 예외를 관찰하지 않았습니다.

CREATE NONCLUSTERED INDEX [T_abcd] ON [dbo].[Table_Z] 
    (
     [abcd] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    GO 
0

난 당신의 코드에서 TABLE_Z 초기에 읽기 잠금을 얻는 것이 문제를 해결할 것이라고 생각합니다.

여기에 대한 질문 : Obtain Update Table Lock at start of Stored Procedure in SQL Server입니다.

편집 : 쓰기 전에 TABLE_Z에서 읽는 중입니다.

A가

B는

A는 쓰기 잠금을하려고 읽기 잠금을 취 읽기 잠금이 필요하지만 B 기다려야합니다 : 당신이 두 개의 스레드/연결 (A & B)이 실행되고 말할 수 읽기 잠금을 해제합니다.

B는 쓰기 잠금을 시도하지만 A가 읽기 잠금을 해제 할 때까지 기다려야합니다.

이제 교착 상태가 발생했습니다.

+0

예를 들어 설명해 주시겠습니까? 테이블 인덱스의 역할이 있습니까? –

관련 문제