2012-12-01 3 views
7

Je n'ai jamais vu cela se produire avant, très étrange.Odd SQL Server 2012 problème IDENTITY

J'ai une base de données SQL Server 2012 Express locale avec laquelle je suis en train de développer. Exécution d'une simple suite de tests en utilisant le plugin TestDrive et en accédant à la base de données avec EF v5.

Je viens d'exécuter un test qui insère un enregistrement dans la base de données. J'avais 9 lignes dans la table allant de l'ID 1-9. L'insertion suivante et l'ID ont sauté par exactement 10000 !!!!

La colonne Id va:

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

Je sais aussi incrémenter inserts échouais l'ID mais je peux garantir que 10 000 ne manqua pas d'insérer dans les 5 secondes entre le test court ...

La structure de la table est vraiment simple, un groupe de colonnes et une colonne d'auto-incrémentation automatique, de type bigint (long), pas de SP, de déclencheurs ou de tout autre contenu programmatique.

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

Très déroutant, quelqu'un d'autre a-t-il vu cela se produire?

+0

Je ne vois pas comment cela peut être mon code. Le code ne fait rien avec l'ID et c'est une commande INSERT, pas une commande UPDATE et si l'INSERT essayait d'appliquer un ID, il ignorait simplement la valeur de l'ID ... – Jammer

+0

Il semble que ce soit un bug en 2012 car il est rapporté ici par d'autres aussi ... http://connect.microsoft.com/SQLServer/feedback/details/743300/identity-column-jumps-by-seed-value#tabs Je viens d'ajouter un journal pour cela comme Eh bien ... – Jammer

+0

On dirait qu'il est causé par un redémarrage du moteur SQL ... mais pourquoi sauter 10000 quand ma graine est 1 est un peu fou ... – Jammer

Répondre

2

Ce blog post a quelques détails supplémentaires. On dirait qu'en 2012, identity est implémenté comme une séquence. Et par défaut, une séquence a un cache. Si le cache est perdu, vous perdez les valeurs de séquence dans le cache.

La solution proposée est de créer une séquence avec no cache:

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

Pour autant que je peux voir, la séquence derrière une colonne d'identité est invisible. Vous ne pouvez pas modifier ses propriétés pour désactiver la mise en cache. Pour utiliser ceci avec Entity Framework, vous pouvez définir StoredGeneratedPattern à Computed de la clé primaire. Ensuite, vous pouvez générer le côté serveur d'identité dans un déclencheur instead of insert:

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 

Si vous trouvez une meilleure solution, laissez-moi savoir :)

+0

Ahhh ... c'est intéressant. Je vais voir si je peux obtenir cette approche sans cache de travail avec EF ... – Jammer

+0

Hmm ...Je vais voir si je peux trouver quelque chose et rendre compte – Jammer

+0

En fait, vous savez quoi, je ne suis même pas sûr que ça m'importe, c'est un bigint donc je ne vais pas Mes identifiants ne sont pas utilisés d'une manière qui dépend de la façon dont ils sont créés et si cela se produit seulement quand SQLServer est redémarré en production qui ne sera pas souvent (les derniers mots célèbres!) ... au moins je Je ne suis pas concerné maintenant, peut-être retourner à 2008 R2 pour le vrai déploiement de production ... – Jammer

0

Si vous appelez la commande « Checkpoint » après chaque requête d'insertion, cela va résoudre votre problème.

Pour plus d'informations, veuillez lire Point de contrôle dans SQL Server

+0

Il y a environ 300 requêtes d'insertion dans la base de données. ne fonctionnerait pas, MS doit résoudre ce problème. –