나는 다음과 같은 테이블이 (여기 엔티티 프레임 워크에서 모델링을하지만, 내 질문은 EF와는 아무 상관이 없습니다) :반복 불가 읽기의 경우입니까?
당신이 볼 수 있듯이, 이것은 버전 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에는 두 트랜잭션 중 두 개의 쿼리가 없습니다.
은 그래서 두 가지 질문 왼쪽 해요 :
- 내 분석이 맞습니까?
- 이러한 종류의 문제를 방지하려면 어떤 격리 수준이 필요합니까?
격리 수준에 영향을주는 다른 요구 사항이 있습니까? http://en.wikipedia.org/wiki/Isolation_(database_systems)에 따르면 ** Serializable ** 격리 수준은 ** Dirty Reads **, ** Non-Repeatable Reads **를 얻지 못한다는 것을 의미합니다. ** Phantom Reads **도 아닙니다. ** Serializable **이 내 문제를 방지한다는 것을 어떻게 알 수 있습니까? – cheeesus