2014-04-22 1 views
1

다음 트랜잭션의 경우 때때로이 트랜잭션이 동일한 순서로 호출 될 때 Dead Lock 오류가 발생합니다.UPDLOCK 힌트의 업데이트 문과 사용법의 DeadLock

BEGIN TRANSACTION 
     IF EXISTS (SELECT orderID FROM [Orders]WHERE [email protected]) 
     BEGIN 
     UPDATE [Orders] SET 
[orderXml] [email protected] 
     ,[updatedDateTime] = @updatedDateTime 
WHERE 
[orderId] = @OrderId AND @updatedDateTime > updatedDateTime 
     END 

if @@ROWCOUNT = 0 
     BEGIN 
      DELETE OrderLine 
      WHERE 
    [email protected] 
     END 

COMMIT TRANSACTION 

교착 그래프 :

<resource-list> 
     <keylock hobtid="72057594039042048" dbid="13" objectname="OrderDB.dbo.Orders" indexname="PK_Order" id="lockac2e8d80" mode="U" associatedObjectId="72057594039042048"> 
     <owner-list> 
      <owner id="process80736748" mode="U"/> 
     </owner-list> 
     <waiter-list> 
      <waiter id="process80739b88" mode="U" requestType="convert"/> 
     </waiter-list> 
     </keylock> 
     <keylock hobtid="72057594039042048" dbid="13" objectname=" OrderDB.dbo.Orders" indexname="PK_Order" id="lockac2e8d80" mode="U" associatedObjectId="72057594039042048"> 
     <owner-list> 
      <owner id="process80739b88" mode="S"/> 
     </owner-list> 
     <waiter-list> 
      <waiter id="process80736748" mode="X" requestType="convert"/> 
     </waiter-list> 
     </keylock> 
    </resource-list> 

PK_Order 주문 테이블 ORDERID (VARCHAR) 열의 기본 키이다. 또한이 테이블에는 updatedDateTime (datetime2) 열에 비 클러스터형 인덱스가 있습니다.

질문 : 위의 업데이트 문에서 WITH (UPDLOCK) 힌트를 사용하면 교착 상태가 사라지는 것처럼 보입니다. UPDLOCK 힌트를 사용하는 것이 좋습니까? 아니면 트랜잭션 격리 수준을 직렬 가능으로 설정해야합니까? 위의 delete 문에도 UPDLOCK 힌트를 사용하는 것이 좋습니다.

답변

1

이것은 교착 상태의 전형적인 경우입니다. 액세스 패턴은 read-then-write입니다. 두 트랜스 읽기 모두 다음 쓰기에 실패합니다.

"쓰기"잠금 (UPDLOCK)을 취하는 해결책이 좋습니다. 이와 비슷한 경우에 가장 좋은 방법이라고 생각되는 UPDLOCK, ROWLOCK, HOLDLOCK을 사용하십시오.

SERIALIZABLE 패턴이 여전히 읽기 - 쓰 기 때문에 도움이되지 않습니다.

DELETE은 트랜잭션이 이미 해당 행에 독점적으로 액세스했기 때문에 추가 잠금이 필요하지 않습니다.