2010-01-03 8 views
2

레코드 버전을 저장할 테이블이 있습니다.추가 버전의 테이블 설정 테이블

열은 : 동일한 ID와 증가의 versionNumber와 함께 테이블에 새 행을 삽입합니다 항목을 저장

Id (Guid) 
VersionNumber (int) 
Title (nvarchar) 
Description (nvarchar) 
etc... 

.

어떻게 순차적 인 VersionNumber 값을 생성하는 것이 가장 좋은지 잘 모르겠습니다. 내 생각은 다음과 같습니다.

SELECT @NewVersionNumber = MAX(VersionNumber) + 1 
FROM VersionTable 
WHERE Id = @ObjectId 

그런 다음 insert 문에 @NewVersionNumber를 사용하십시오.

이 방법을 사용하면 동시 처리 문제를 피하기 위해 트랜잭션을 직렬 가능으로 설정해야합니까? 동일한 ID에 대해 중복 된 VersionNumbers를 사용하고 싶지 않습니다.

이렇게하면 직렬화 가능 트랜잭션을 사용하지 않는 더 좋은 방법이 있습니까?

+0

@Brownie - 내 대답의 안전성에 대한 내 질문에 명확한 응답이 아직 없습니다. 잠자기 후 다시 확인하십시오 - 가능하면 내 대답을 삭제할 수 있습니다 (나는 길을 잃을 수 있습니다.). 좋은 정보가 있습니다. 특히 쿼리 힌트를 안전하게 만들 수있는 테이블 힌트와 같은 메서드에 대한 정보가 있습니다. 그래도 제약 조건을 사용하는 것이 아마도 가장 간단하고 안전한 방법 일 것입니다. –

답변

2

동시성 문제 (또는 특정 경우 중복 삽입)를 피하기 위해 ID 및 VersionNumber 열로 구성된 테이블의 기본 키로 복합 키를 만들 수 있습니다. 그러면 키 열에 고유 한 제한 조건이 적용됩니다.

다음으로 삽입 루틴/논리를 사용하여 중복 키로 인한 삽입 오류를 처리하거나 CATCH 한 다음 단순히 삽입 프로세스를 다시 발행 할 수 있습니다.

SQL Server 복제 또는 여러 데이터 원본을 사용하기 때문에 특히 GUID를 사용해야하는 경우가 아니면 BIGINT와 같은 대체 데이터 형식을 사용하는 것이 좋습니다.

+0

그래서 실패하면 예외가 발생하고 성공하면 추가 비용이 거의 들지 않습니다. 굉장해. 불행히도이 경우 Guid가되어야합니다. – Brownie

2

나는 다음과 같은 단일 삽입 문은 동시성 문제를 방지 것이라고 생각했지만, my question here에 Heinzi의 훌륭한 대답 후이 안전 전혀 아니라고 밝혀 :

Insert Into VersionTable 
(Id, VersionNumber, Title, Description, ...) 
Select @ObjectId, max(VersionNumber) + 1, @Title, @Description 
From VersionTable 
Where Id = @ObjectId 

난 그냥 그것을 떠날거야 참고. 물론 이것은 테이블 힌트 또는 Serializable의 트랜잭션 격리 수준에서 작동하지만 전체적으로 가장 좋은 솔루션은 제약 조건을 사용하는 것입니다.

+0

+1. "단일 SQL 문에 물건을 넣으면 동시성 문제가 해결됩니다"는 일반적인 오해입니다. 따라서 여기에 대한 답을 참조로하는 것이 좋습니다. – Heinzi