Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden

Hibernate: Sprünge beim Autoincrement

So ein SequenceGenerator ist schon eine feine Sache, vor­al­lem bei der Verwendung von Relationalen Datenbanksystemen á la Oracle. Musste man sich ohne die Vorzüge des ORM (Object-Relational-Mapping) noch mit der hän­di­schen Erstellung von Sequenzen zur Incrementierung von Werten her­um­schla­gen, erle­digt Hibernate das Ganze voll auto­ma­tisch mit zwei Zeilen Code.

Die Tücken der Technik

In mei­nem letz­ten Projekt zeigte sich jedoch ein inter­es­san­tes Phänomen: Ich erstellte eine Klasse mit Annotation und einer Autoincrement-Sequence zum Hochzählen der Id.

@Entity
@SequenceGenerator(name = "user_seq", sequenceName = "user_id_seq")
public class User implements Serializable { ... }

Zunächst schien alles zu funk­tio­nie­ren, als ich aber einige Zeit spä­ter in die Datenbank schaute ent­deckte ich selt­same Sprünge zwi­schen den Ids:

 

id

name

age

50

Fred

31

51

Harry

25

100

Mike

13

101

Frank

46

102

Richard

52

150

Ted

31

151

Kyle

29

152

Steve

34

153

Michael

42

 

Nach eini­gem Probieren stellte ich fest, dass die Sprünge stets nach dem Neustart der Anwendung auf­tra­ten. Das Problem konnte ich schließ­lich nach etwas Recherche im Internet aus­ma­chen. Für den SequenceGenerator exis­tiert ein Parameter allocationSize, wel­cher die defi­nierte Sequenz um den ange­ge­ben Wert erhöht und anschlie­ßend diese Nummern ver­gibt. Erst wenn alle ver­braucht sind, wird die Sequenz erneut auf­ge­ru­fen. Der Nachteil die­ser per­for­man­ten Vorgehensweise ist, dass bei einem Neustart der Anwendung die zwi­scheng­spei­cher­ten Werte ver­lo­ren gehen und dadurch Lücken zwi­schen den Id's ent­ste­hen. Standardmäßig ist diese Einstellung auf 50 gesetzt, was auch den Abstand in der Datenbank erklärt. Die nach­fol­gende Einstellung schafft also Abhilfe:

@Entity
@SequenceGenerator(name = "user_seq", sequenceName = "user_id_seq" allocationSize=1)
public class User implements Serializable { ... }

Nun wird zur Generierung des nächs­ten Primary-Keys immer die Datenbanksequenz bemüht, was die Performance zwar etwas min­dert, jedoch blei­ben die Lücken aus.

 

Links: http://www.galileocomputing.de/artikel/gp/artikelID-328

Related Posts

1 Kommentar

Nun, es min­dert die Performance nicht nur ein biss­chen… je nach Traffic / Anzahl gleich­zei­ti­gen Sessions ist das sogar ein wich­ti­ger Bottleneck. Daher gibt es die­sen Parameter, den die meis­ten PHP, Ruby, … Programmierer aller­dings über­haupt nicht ken­nen. 😉 Und wen inter­es­sie­ren schon Sprünge in einer 64Bit Zahl.

Comments are closed.

Pin It on Pinterest