Ich habe eine .net-Transaktion mit einer SQL-Einfügung in eine SQL Server 2005-Datenbank. Die Tabelle hat einen Identitätsprimärschlüssel.
Wenn ein Fehler innerhalb der Transaktion auftritt, Rollback()
wird aufgerufen. Die Zeileneinfügungen werden korrekt zurückgesetzt. Wenn ich jedoch das nächste Mal Daten in die Tabelle einfüge, wird die Identität erhöht, als ob das Zurücksetzen nie stattgefunden hätte. Es gibt also im Wesentlichen Lücken in der Identitätssequenz. Gibt es eine Möglichkeit, mit der Rollback()
Methode die fehlende Identität zurückzugewinnen?
Nähere ich mich dem nicht richtig?
Antworten:
Wenn Sie darüber nachdenken, sollte die Auto-Inkrement-Nummer nicht transaktional sein. Wenn andere Transaktionen warten müssten, um zu sehen, ob die automatische Nummer verwendet oder "zurückgesetzt" werden würde, würden sie von der vorhandenen Transaktion unter Verwendung der automatischen Nummer blockiert. Betrachten Sie beispielsweise meinen Pseudocode unten mit Tabelle A unter Verwendung eines Felds für die automatische Nummerierung für die ID-Spalte:
User 1 ------------ begin transaction insert into A ... insert into B ... update C ... insert into D ... commit User 2 ----------- begin transaction insert into A ... insert into B ... commit
Wenn die Transaktion von Benutzer 2 eine Millisekunde nach der von Benutzer 1 beginnt, muss die Einfügung in Tabelle A warten, bis die gesamte Transaktion von Benutzer 1 abgeschlossen ist, um festzustellen, ob die automatische Nummer von der ersten Einfügung in A verwendet wurde.
Dies ist eine Funktion, kein Fehler. Ich würde empfehlen, ein anderes Schema zu verwenden, um automatische Nummern zu generieren, wenn diese eng aufeinander folgen müssen.
quelle
Wenn Sie darauf angewiesen sind, dass Ihre Identitätswerte lückenlos sind, dann ja - Sie machen es falsch. Der springende Punkt eines Ersatzschlüssels ist, keine geschäftliche Bedeutung zu haben .
Und nein, es gibt keine Möglichkeit, dieses Verhalten zu ändern (es sei denn, Sie rollen Ihr eigenes Autoincrement und leiden unter den Leistungsfolgen des Blockierens anderer Inserts).
quelle
Sie erhalten Lücken in Ihrer Sequenz, wenn Sie auch
DELETE
eine Zeile.Sequenzen müssen eindeutig sein, aber nicht sequentiell. Die Tatsache, dass sie monoton zunehmen, ist nur ein Zufall bei der Umsetzung.
quelle
Soweit ich weiß, beanspruchen die Zeilen zum Einfügen die Autonummer und beim Rollback geht diese Nummer endgültig verloren. Wenn Sie darauf angewiesen sind, dass diese automatische Nummerierung in der Sequenzierung ausgeführt wird, sollten Sie den von Ihnen verwendeten Ansatz berücksichtigen.
quelle
Alle anderen Plakate, die sagen, dass sie sich keine Sorgen machen sollen und dass Sie Lücken bekommen sollten , haben Recht. Wenn die Zahl eine geschäftliche Bedeutung hat und diese Bedeutung nicht mit Lücken verbunden ist, verwenden Sie keine Identitätsspalte.
Zu Ihrer Information, wenn Sie aus irgendeinem Grund die Lücken entfernen möchten, haben die meisten Datenbanken die Möglichkeit, die automatische Nummerierung auf die Nummer Ihrer Wahl zu setzen. Es ist ein Schmerz im Arsch, und wenn Sie es regelmäßig tun müssen, sollten Sie definitiv kein Autonumber / Identity-Feld verwenden, wie oben erwähnt. Aber hier ist der Code, um es in SQL Server zu tun:
DBCC-CHECKIDENT ('Produkt', RESEED, 0)
Dadurch wird die Produkttabelle auf 1 zurückgesetzt. Wenn Sie jedoch Datensätze in der Tabelle haben, werden die bereits verwendeten ID-Werte offensichtlich übersprungen.) Andere RDBMS-Anbieter haben ihre eigene Syntax, aber der Effekt ist ungefähr der gleiche. Suchen Sie daher in den Systemhilfedateien oder im Internet nach "reseed identity" oder "reseed autonumber".
Nochmals: Dies ist für besondere Anlässe, nicht für den regelmäßigen Gebrauch. Legen Sie es nicht in eine gespeicherte Prozedur und lassen Sie uns alle dorthin kommen.
quelle
Ich glaube nicht, dass automatisch nummerierte Schlüssel sequentiell sein müssen. Tatsächlich glaube ich nicht, dass sie erforderlich sein können:
Transaktion a startet und fügt ein
Transaktion b startet und fügt ein
Transaktion a bricht ab
Du bekommst ein Loch. nichts dagegen zu tun.
quelle
Muhan versucht, dies im Zusammenhang mit vielen gleichzeitigen Verbindungen zu betrachten, die diese Transaktion ausführen, und nicht nacheinander. Einige werden scheitern und andere werden erfolgreich sein. Sie möchten, dass sich SQL Server darauf konzentriert, die neuen Anforderungen beim Eingang auszuführen und keine lückenlose Identitätsspalte beizubehalten. IMO it (Lücken in den Werten) ist definitiv etwas, für das es sich nicht lohnt, Zeit zu investieren.
quelle
Nein. Sequenzimplementierungen verwenden eine autonome Transaktion. In Oracle befand sich die autonome Transaktion früher in der Datenbank, wird jetzt jedoch für den eigenen Gebrauch verfügbar gemacht (und häufig falsch verwendet).
PRAGMA AUTONOMOUS_TRANSACTION;'
quelle