2013-08-12 4 views
1

나는 다음과 같은 테이블이 (여기 엔티티 프레임 워크에서 모델링을하지만, 내 질문은 EF와는 아무 상관이 없습니다) :반복 불가 읽기의 경우입니까?

enter image description here

당신이 볼 수 있듯이, 이것은 버전 Product 테이블입니다. Id 열이 기본 키이지만 (EntityId, VersionId) 조합도 기본 키가 될 수 있습니다. EntityId은 엔티티의 다른 버전간에 일정한 엔티티의 ID를 나타냅니다. 엔티티는 IsDeleted = 1 행을 써서 삭제됩니다.

데이터 조작을 담당하는 저장 프로 시저가 데이터 조작이 올바른지 먼저 확인합니다. 예를 들어 UPDATE SP는 엔티티가 이미 삭제되었는지 확인합니다. 이 모든 잘 작동

(pseudo-code): 

sp_Product_Update: 
(1) IF EXISTS (SELECT Id FROM Product WHERE IsDeleted = 1 AND EntityId = @ProductId) 
     RAISERROR "Entity has already been deleted" 
     RETURN 
(2) INSERT INTO Versions ... 
(3) INSERT INTO Product ... (IsDeleted = 0) 

sp_Product_Delete: 
(1) IF EXISTS (SELECT Id FROM Product WHERE IsDeleted = 1 AND EntityId = @ProductId) 
     RAISERROR "Entity has already been deleted" 
     RETURN 
(2) INSERT INTO Versions ... 
(3) INSERT INTO Product ... (IsDeleted = 1) 

: 그 검사가 성공하면, SP의는 Product 테이블에 새 행 다음 버전 테이블에 새 행을 생성합니다.

현재이 문제를 동시성 문제로 분석하고 있습니다. 동일한 개체에 대한 두 개의 SP를 동시에 호출되는 다음 동시성 시나리오를 상상해 : 당신이 볼 수 있듯이

Transaction 1       Transaction 2 
sp_Product_Update      sp_Product_Delete 

(1) Check succeeds, entity has not yet been deleted. 

             (1) Same check. 

             (2) INSERT INTO Versions... 
             (3) INSERT INTO Product.. (IsDeleted = 1) 

(2) INSERT INTO Versions... 
(3) INSERT INTO Product ... (IsDeleted = 0) 

이 경쟁 조건이 일치하지 않는 데이터,을 한 후 온다 즉 IsDeleted = 0 행에 이르게 IsDeleted = 1 항목.

그래서 우리는이 경쟁 조건을 피하기 위해 어떤 격리 수준이 필요한지 결정해야합니다.

  • 이 (1) 깨끗한 지에서 읽을 데이터 때문에, 더러운 읽기로 표시되지 않습니다.
  • 아니요 반복 불가능한 읽기 읽기 또는 두 가지 읽기 작업이 없습니다.
  • 같음 팬텀 Read에는 두 트랜잭션 중 두 개의 쿼리가 없습니다.

은 그래서 두 가지 질문 왼쪽 해요 :

  • 내 분석이 맞습니까?
  • 이러한 종류의 문제를 방지하려면 어떤 격리 수준이 필요합니까?

답변

1

해결 방법은 모든 명령을 하나의 원자 작업으로 함께 실행해야하므로 직렬 가능 격리 수준이 필요합니다.

저장 프로 시저를 사용하지 않는 경우 높은 처리량으로 이러한 상황을 위해 설계된 optimistic locking을 사용하는 것이 좋습니다.

+0

격리 수준에 영향을주는 다른 요구 사항이 있습니까? http://en.wikipedia.org/wiki/Isolation_(database_systems)에 따르면 ** Serializable ** 격리 수준은 ** Dirty Reads **, ** Non-Repeatable Reads **를 얻지 못한다는 것을 의미합니다. ** Phantom Reads **도 아닙니다. ** Serializable **이 내 문제를 방지한다는 것을 어떻게 알 수 있습니까? – cheeesus