8
votes

Transactions de base de données non engagées et colonnes auto-incréments

J'ai rencontré un comportement curieux aujourd'hui et je me demandais s'il est attendu ou standard. Nous utilisons Hibernate contre MySQL5. Au cours du codage, j'ai oublié de fermer une transaction, je suppose que d'autres peuvent se rapporter.

Lorsque j'ai finalement fermé la transaction, dirigez le code et vérifié la table, j'ai remarqué ce qui suit. Toutes les fois où j'ai manqué mon code sans fermer la transaction, ce qui n'a donc pas entraîné d'insérer des lignes réelles, incrémenté néanmoins la valeur de clé primaire de substitution automatique, de sorte que j'ai une lacune (c.-à-d. Pas de lignes avec une valeur de champ d'identification 751 à 762).

est-ce que ce comportement attendu ou standard? Pourrait-il varier en fonction de la base de données? Et / ou l'abstraction de transaction de Hibernate a-t-elle un effet possible sur cela?


2 commentaires

Je connaissais la réponse, mais c'est toujours une question intéressante!


Idéalement, votre application / conception ne doit pas être affectée par des lacunes dans la séquence - vous ne devriez jamais vous faire entrer dans une situation où cela compte réellement


4 Réponses :


8
votes

oui c'est attendu.

Si vous y pensez: quoi d'autre peut faire la base de données? Si vous augmentez la colonne, puis utilisez-la comme une clé étrangère dans d'autres inserts dans la même transaction et pendant que vous faites que quelqu'un d'autre s'engage, ils ne peuvent pas utiliser votre valeur. Vous obtiendrez un écart.

séquences dans des bases de données telles que Oracle Travail de la même manière. Une fois qu'une valeur particulière est demandée, si elle est alors engagée n'a pas d'importance. Ça ne sera jamais réutilisé. Et des séquences ne sont pas absolument ordonnées aussi.


0 commentaires

6
votes

C'est un comportement attendu à peu près. Avec l'extérieur, le DB devrait attendre chaque transaction qui a inséré un enregistrement à compléter avant d'attribuer un nouvel ID à l'insert suivant.


0 commentaires

5
votes

Oui, c'est le comportement attendu. Cette documentation l'explique très bien .

Commencer avec 5.1.22, il existe en fait trois modes de verrouillage différents qui contrôlent la manière dont les transactions simultanées obtiennent des valeurs d'incrémentation automatique. Mais tous les trois causeront des lacunes pour les transactions roulées (les valeurs d'incrémentation automatique utilisées par la transaction roulée seront jetées).


0 commentaires

0
votes

Les séquences de base de données ne doivent pas garantir la séquence d'identification sans lacunes. Ils sont conçus pour être indépendants de transaction, uniquement de cette manière peuvent être non bloquants.

Vous ne voulez pas de lacunes, vous devez écrire votre propre procédure stockée pour augmenter la colonne transactionnelle, mais ce code bloquera d'autres transactions, vous devez donc être carreful.

Vous sélectionnez Curval de Séquence_Table où Type =: Your_Seq_Name pour la mise à jour; Mise à jour Séquence_Table Set Curval =: incrémented_currval où Type =: Your_seq.


0 commentaires