Wir laufen SQL Server 2012 SP1 x64 (11.0.3000.0)SQL Server: beliebig Autoinkrement der Primärschlüssel
Ich habe die folgende Tabelle mit dem InvoiceId
Feld als Auto-Inkrementierung, Primärschlüssel:
CREATE TABLE Orders(
InvoiceId bigint IDENTITY(1001,1) NOT FOR REPLICATION,
OrderId varchar(8) NOT NULL,
... -- other fields removed for brevity
CONSTRAINT [PK_ORDERS] PRIMARY KEY CLUSTERED (InvoiceId)
ON [PRIMARY],
)
New Zeilen eingefügt werden, obwohl eine einfache gespeicherte Prozedur wie folgt aus:
SET XACT_ABORT ON
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO Orders(
OrderId,
... -- other fields removed for brevity
)
VALUES (
@orderId,
...
)
SELECT @newRowId = SCOPE_IDENTITY()
COMMIT TRANSACTION
die obige sproc gibt die neu erstellten Zeilennummer (Orders.InvoiceId
) an den Anrufer.
Der Code funktionierte perfekt, mit [InvoiceId]
beginnend von 1001 und inkrementiert um 1 für jede nachfolgende Inserts.
Unsere Benutzer eingefügt etwa 130 Zeilen. [InvoiceId]
war um 1130, dann auf den nächsten Einsatz seinen Wert sprang auf !
Hier ist die Daten Screenshot:
Ich bin ratlos, was hier gerade passiert ist. Warum hat der Auto-Inc-Zähler plötzlich fast 10.000 Punkte übersprungen?
Wir verwenden den Wert [InvoiceId]
, um Barcodes zu generieren. Daher bevorzugen wir, dass der Wert in einem bestimmten Bereich bleibt, vorzugsweise in einer zusammenhängenden Reihe.
Ich habe die T-SQL-Dokumentation gelesen, konnte aber nichts zu meinem Problem finden. Ist das das normale Verhalten (beliebige Population) eines Identitätsfeldes?
UPDATE Danke an Marting & Aron, ich habe ein Workaround gefunden. Hier ist die official response von Microsoft:
In SQL Server 2012 die Implementierung der Identität Eigenschaft hat geändert Investitionen in andere Merkmale aufzunehmen. In früheren Versionen von SQL Server basierte die Überwachung der Identitätsgenerierung auf Transaktionsprotokolleinträge für jeden generierten Identitätswert. In SQL Server 2012 generieren wir Identitätswerte in Batches und protokollieren nur den Maximalwert des Batches . Dies reduziert die Menge und die Häufigkeit von Informationen, die in die Transaktionsprotokollverbesserung Skalierbarkeit geschrieben werden.
Wenn Sie benötigen, um die gleiche Identität Generation Semantik wie in früheren Versionen von SQL Server gibt es zwei Möglichkeiten zur Verfügung:
• Verwenden Sie Trace-Flag 272 o Das wird ein Protokolleintrag führen für jede erzeugte Identität erzeugt werden Wert. Die Leistung der Identitätsgenerierung kann von beeinflusst werden, indem dieses Ablaufverfolgungsflag aktiviert wird.
• Verwendung Generator eine Sequenz mit der NO CACHE Einstellung (http://msdn.microsoft.com/en-us/library/ff878091.aspx) o Dieses wird eine Protokollaufzeichnung verursachen für jede erzeugte Folge Wert erzeugt werden. Beachten Sie, dass die Leistung der Sequenzwertgenerierung beeinträchtigt werden kann, indem NO CACHE verwendet wird.
Beispiel:
CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE;
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL);
'IDENTITY' noch nie zusammenhängende garantiert, aber es ist ein bekanntes Problem im Jahr 2012, wo es plötzlich große Lücken zu verlassen, nachdem den Dienst springen kann neu gestartet werden. –
Danke @MartinSmith! Dies scheint das Problem in meinem Fall zu sein. Ich erinnere mich daran, die db-Maschine vor dem Identity Increment-Sprung neu zu starten! Wie kann ich das vermeiden? – masroore
Sie können es nicht sicher vermeiden, da Kontiguität nie garantiert wurde, aber es gibt ein Ablaufverfolgungsflag, das Sie festlegen können, um das langsamere (protokollierte) Verhalten von 2008 zu erhalten, oder Sie können eine Sequenz mit einer kleineren Cachegröße verwenden. Siehe [die Diskussion hier] (https://connect.microsoft.com/SQLServer/feedback/details/739013/failover-or-restar-results-in-reseed-ofidentity) –