Nicht festgeschriebene Datenbanktransaktionen und Spalten mit automatischer Inkrementierung

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 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?

    
George Jempty 09.09.2009, 14:09
quelle

4 Antworten

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.

    
cletus 09.09.2009, 14:12
quelle
6

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.

    
Gareth Davis 09.09.2009 14:12
quelle
5

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).

    
nathan 09.09.2009 14:14
quelle
0

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.

    
стривігор 15.02.2011 12:10
quelle