2009-09-09 5 views
8

Ich bin heute auf merkwürdiges Verhalten gestoßen und habe mich gefragt, ob es erwartet wird oder Standard ist. Wir verwenden Hibernate gegen MySQL5. Im Laufe der Programmierung habe ich vergessen, eine Transaktion abzuschließen, ich nehme an, dass andere sich darauf beziehen können.Nicht festgeschriebene Datenbanktransaktionen und automatisch inkrementierte Spalten

Als ich schließlich die Transaktion geschlossen, lief der Code und überprüfte die Tabelle, bemerkte ich Folgendes. Alle Male habe ich meinen Code falsch ausgeführt, ohne die Transaktion zu beenden, was nicht dazu führte, dass tatsächlich Zeilen eingefügt wurden, trotzdem erhöhte ich den Primärschlüsselwert des Autoinkrementierungs-Ersatzschlüssels, so dass ich eine Lücke (dh keine Zeilen mit dem ID-Feldwert von 751 bis 762).

Ist dies erwartet oder Standardverhalten? Könnte es abhängig von der Datenbank variieren? Und/oder hat die Hibernate-eigene Transaktionsabstraktion einen möglichen Einfluss darauf?

+0

Ich wusste die Antwort, aber das ist immer noch eine interessante Frage! – RichardOD

+1

Idealerweise sollte Ihre Anwendung/Ihr Design nicht durch irgendwelche Lücken in der Sequenz beeinträchtigt werden - Sie sollten sich nie in einer Situation befinden, in der dies tatsächlich von Bedeutung ist –

Antwort

8

Ja das ist zu erwarten.

Wenn Sie darüber nachdenken: Was kann die Datenbank noch tun? Wenn Sie die Spalte inkrementieren und diese dann als Fremdschlüssel in anderen Einfügungen innerhalb derselben Transaktion verwenden, können Sie Ihren Wert nicht verwenden, während eine andere Person dies festlegt. Du wirst eine Lücke bekommen.

Sequenzen in Datenbanken wie Oracle arbeiten auf die gleiche Weise. Sobald ein bestimmter Wert angefordert wird, spielt es keine Rolle, ob er dann ausgeführt wird oder nicht. Es wird nie wiederverwendet werden. Und Sequenzen sind auch nicht absolut geordnet.

6

Es ist ziemlich erwartet Verhalten. Ohne sie müsste die Datenbank auf jede Transaktion, die einen Datensatz eingefügt hat, warten, bevor sie der nächsten Einfügung eine neue ID zuweist.

5

Ja, das ist das erwartete Verhalten. This documentation erklärt es sehr gut.

Beginnend mit 5.1.22 gibt es tatsächlich drei verschiedene Sperrmodi, die steuern, wie gleichzeitige Transaktionen Auto-Inkrementwerte erhalten. Aber alle drei führen zu Lücken für rückgängig gemachte Transaktionen (Auto-Inkrementwerte, die von der zurückgesetzten Transaktion verwendet werden, werden verworfen).

0

Datenbanksequenzen sind keine Id-Sequenz ohne Lücken zu garantieren. Sie sind so konzipiert, dass sie transaktionsunabhängig sind, nur so können sie nicht blockierend sein.

Sie wollen keine Lücken, Sie müssen Ihre eigene gespeicherte Prozedur schreiben, um die Spalte transaktional zu erhöhen, aber solcher Code wird andere Transaktionen blockieren, also müssen Sie Carrefull sein.

Sie SELECT CURRVAL VON SEQUENCE_TABLE WHERE TYPE =: YOUR_SEQ_NAME FÜR UPDATE; AKTUALISIEREN SEQUENCE_TABLE SET CURRVAL =: INCREMENTED_CURRVAL WHERE TYPE =: YOUR_SEQ.

Verwandte Themen