2012-12-01 3 views
7

이전에는 이런 일이 일어난 적이 한번도 보지 못했습니다. 매우 이상합니다.Odd SQL Server 2012 IDENTITY 문제

내가 개발중인 로컬 SQL Server 2012 Express 데이터베이스가 있습니다. TestDrive 플러그인을 사용하여 간단한 테스트를 실행하고 EF v5로 데이터베이스에 액세스합니다.

방금 ​​데이터베이스에 레코드를 삽입하는 테스트를 실행했습니다. 나는 ID 1-9에서 진행되는 테이블에서 9 개의 행을 가졌습니다. 다음 인서트와 ID는 정확히 10000에 달했다 !!!

ID 열에 간다 : 나는 삽입은 또한 ID를 증가하지만 만 테스트가 실행 사이에 5 초 단위로의 삽입에 실패하지 않았다는 것을 보장 할 수 실패 알고

1, 2, 3, 4, 5, 6, 7, 8, 9, 10009 

...

테이블 구조는 실제로 간단하고, 일련의 열과 자동 증분, ID 유형이 bigint (길다), SP, 트리거 또는 기타 프로그래밍 방식의 내용이 없습니다.

[Id] [bigint] IDENTITY(1,1) NOT NULL, 

매우 혼란스러운 사람이 누구일까요?

+0

내 코드가 될 수는 없습니다. 이 코드는 ID와 관련하여 아무 것도하지 않으며 INSERT 명령이며 UPDATE 명령이 아니며 INSERT가 ID를 적용하려고하면 ID 값을 무시합니다. – Jammer

+0

2012 년 버그 일 수 있습니다 다른 사람들도 여기에보고했습니다 ... http://connect.microsoft.com/SQLServer/feedback/details/743300/identity-column-jumps-by-seed-value#tabs 방금이 로그를 다음과 같이 추가했습니다. 음 ... – Jammer

+0

SQL 엔진을 다시 시작한 것으로 보입니다.하지만 내 시드가 1 일 때 10000으로 점프하는 이유는 조금 미친 것입니다 ... – Jammer

답변

2

blog post에는 몇 가지 추가 세부 정보가 있습니다. 2012 년과 같이 identity이 시퀀스로 구현됩니다. 기본적으로 시퀀스에는 캐시가 있습니다. 캐시가 손실되면 캐시의 순서 값이 손실됩니다.

제안 된 솔루션은 no cache으로 시퀀스를 생성하는 것입니다 :

CREATE SEQUENCE TEST_Sequence 
    AS INT 
    START WITH 1 
    INCREMENT BY 1 
    NO CACHE 

가 최대한 멀리 볼 수, ID 열 뒤에 순서가 보이지 않습니다. 캐싱을 사용하지 않으려면 속성을 변경할 수 없습니다.

이 키를 Entity Framework에서 사용하려면 기본 키의 StoredGeneratedPatternComputed으로 설정할 수 있습니다. 그럼 당신은 instead of insert 트리거의 ID 서버 측 생성 할 수 있습니다 : 당신이 더 나은 해결책을 찾을 경우

if exists (select * from sys.sequences where name = 'Sequence1') 
    drop sequence Sequence1 
if exists (select * from sys.tables where name = 'Table1') 
    drop table Table1 
if exists (select * from sys.triggers where name = 'Trigger1') 
    drop trigger Trigger1 
go 
create sequence Sequence1 
    as int 
    start with 1 
    increment by 1 
    no cache 
go 
create table Table1 
    (
    id int primary key, 
    col1 varchar(50) 
    ) 
go 
create trigger Trigger1 
    on Table1 
    instead of insert 
as 
insert Table1 
     (ID, col1) 
select next value for Sequence1 
,  col1 
from inserted 
go 
insert Table1 (col1) values ('row1'); 
insert Table1 (col1) values ('row2'); 
insert Table1 (col1) values ('row3'); 

select * 
from Table1 

을, 당신은 "체크 포인트"명령 각 삽입 쿼리 이후에 호출하는 경우 나 :

+0

아 ... 흥미 롭군요. EF로 작업하는이 캐시 접근법을 얻을 수 있는지 알 수 있습니다 ... – Jammer

+0

흠 ...그 모든 것이 나에게 조금 어수선 해 보인다. (내가 그것에 관해 무엇이라도 발견 할 수 있으면 나는 볼 것이다. 그리고 – Jammer

+0

실제로, 당신은 알고있다. 나는 심지어 내가 걱정하고있다라고 확신하지 않는다. 그래서 bigint이다. 그래서 나는 가고 있지 않다. 내 ID는 어떤 방식 으로든 사용되지 않으며, SQLServer가 자주 시작되는 프로덕션 환경에서 다시 시작될 때만 발생합니다 (유명한 마지막 단어!) ... 적어도 지금은 염려하지 않는다. 실제 생산을위한 2008 R2 R2로 되돌아 갈 수있다 ... – Jammer

0

을 알려주세요 그것은 당신의 문제를 해결할 것입니다.

자세한 내용은 SQL Server의 체크 포인트

+0

DB에 약 300 개의 삽입 쿼리가있다. MS는이 문제를 해결해야합니다. –