2012-12-01 25 views
7

Bunu daha önce hiç görmedim, çok garip.Odd SQL Server 2012 KİMLİK sorunu

Karşılaştığım yerel bir SQL Server 2012 Express veritabanım var. TestDrive eklentisini kullanarak ve EF v5 ile veritabanına erişerek basit bir test paketi çalıştırıyor.

Sadece veritabanına kayıt ekleyen bir sınama yürüttüm. Tabloda 9 - 9 arası bir kimlik vardı. Bir sonraki insert ve kimlik tam olarak 10000 atladı !!

Kimliği sütunu gider: Ben uçlar da kimliğini artırmaz ama 10.000 test çalıştırır arasında 5 saniye içinde eklemek için başarısız olmadığını garanti edemez başarısız biliyorum

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

...

Tablo yapısı gerçekten çok basit, bir grup sütun ve bir otomatik artım, bigint (uzun) tip kimlik sütunu, SP yok, tetikleyici veya başka herhangi bir programatik içeriğe sahip.

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

Çok kafa karıştırıcı, bunun olduğunu gören başka biri var mı?

+0

Kodumun nasıl olabileceğini anlamıyorum. Kod, ID ile bir şey yapmaz ve bir INSERT komutu, bir UPDATE komutu değil ve eğer INSERT bir ID uygulamayı denediyse, sadece ID değerini göz ardı eder ... – Jammer

+0

Bu, 2012'de bir hata olabilir. Diğerleri tarafından da burada bildirildi ... http://connect.microsoft.com/SQLServer/feedback/details/743300/identity-column-jumps-by-seed-value#tabs Bunun için bir günlük ekledim iyi ... – Jammer

+0

SQL motorunun yeniden başlatılmasından kaynaklanıyormuş gibi görünüyor ... ama neden 10000'ım tohumum 1'in biraz deli olduğu zaman atlıyor ... – Jammer

cevap

2

Bu blog post bazı ek ayrıntılara sahiptir. 2012 yılında göründüğü gibi, identity bir dizi olarak uygulanmaktadır. Ve varsayılan olarak, bir sıra bir önbelleğe sahiptir. Önbellek kaybolursa, önbellekteki sıra değerlerini kaybedersiniz.

önerilen çözüm no cache olan bir dizi oluşturmak için:

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

kadarıyla görüldüğü gibi, bir kimlik sütunu arkasında dizisi görünmezdir. Önbelleğe almayı devre dışı bırakmak için özelliklerini değiştiremezsiniz.

Bunu Entity Framework ile kullanmak için, birincil anahtarın StoredGeneratedPattern değerini Computed olarak ayarlayabilirsiniz. Sonra bir instead of insert tetikleyici kimlik sunucu tarafı yaratabilecek: Eğer daha iyi bir çözüm bulursanız

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 

, siz "Checkpoint" komutu her insert sorgusu sonrasında arayacak olursa bana :)

+0

Ahhh ... bu ilginç. EF ile çalışacak hiçbir önbellek yaklaşımı alıp alamayacağımı göreceğim ... – Jammer

+0

Hmm ...hepsi bana biraz dağınık görünüyor: (Bu konuda bir şey bulabilirim ve geri bildirimde bulunup görmeyeceğimi göreceğim) – Jammer

+0

Aslında, bilirsin, umurumda değil, umurumda değil. Yakında tükeniyor Ids'larım, nasıl oluşturulduklarına bağlı olarak herhangi bir şekilde kullanılmıyorlar ve eğer sadece SQLServer sık ​​sık olmayacak bir prodüksiyonda (ünlü son sözler!) yeniden başlatılırsa ... Şimdi endişe duymuyorum, gerçek üretim dağıtımı için 2008 R2'ye geri dönebiliriz ... – Jammer

0

bildirin problemini çözecek.

Daha fazla bilgi için lütfen SQL Server'da Denetim Noktası'nı okuyun.

+0

DB'de yaklaşık 300 ekleme sorgusu var. işe yaramaz, MS bu sorunu düzeltmeli. –

İlgili konular