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 zu schließen. Ich nehme an, dass andere sich darauf beziehen können.
Als ich schließlich die Transaktion geschlossen, den Code ausgeführt und die Tabelle überprüft habe, ist mir folgendes aufgefallen. All die Male, die ich fälschlicherweise meinen Code ausgeführt habe, ohne die Transaktion zu schließen, was nicht dazu führte, dass tatsächlich Zeilen eingefügt wurden, erhöhte trotzdem 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 das erwartet oder Standardverhalten? Könnte es abhängig von der Datenbank variieren? Und / oder hat die Hibernate-eigene Transaktionsabstraktion einen möglichen Einfluss darauf?
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.
Es ist ziemlich erwartetes Verhalten. Ohne sie müsste die Datenbank warten, bis jede Transaktion, die einen Datensatz eingefügt hat, abgeschlossen ist, bevor der nächsten Einfügung eine neue ID zugewiesen wird.
Ja, das ist das erwartete Verhalten. Diese Dokumentation erklärt es sehr gut.
Ab 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 Rollback-Transaktionen (Auto-Increment-Werte, die von der Rollback-Transaktion verwendet werden, werden verworfen).
Datenbanksequenzen sind keine lückenlose ID-Sequenz. Sie sind so konzipiert, dass sie transaktionsunabhängig sind, nur so können sie nicht blockierend sein.
Sie möchten 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 vorsichtig sein.
Sie wählen CURRVAL AUS SEQUENCE_TABLE WHERE TYPE =: YOUR_SEQ_NAME FÜR UPDATE; UPDATE SEQUENCE_TABLE SET CURRVAL =: INCREMENTED_CURRVAL WO TYPE =: YOUR_SEQ.
Tags und Links java mysql hibernate auto-increment transactions