Ne Hibernate annulation de la transaction supprimer “de la session.flush()”ed entités?
J'ai été confus au sujet de transaction.rollback
. Ici est un exemple de pseudo-code:
transaction = session.beginTransaction()
EntityA a = new EntityA();
session.save(a);
session.flush();
transaction.rollback();
Ce qui se passe lorsque ce code fonctionne? Dois-je l'entité dans la base de données ou pas?
Vous devez vous connecter pour publier un commentaire.
Réponse courte: Non, vous n'aurez pas d'entité dans la base de données.
Réponds plus: mise en veille prolongée est assez intelligent pour ne pas envoyer insérer/mises à jour de la DB jusqu'à ce qu'il sait si la transaction va être validée ou annulée (bien que ce comportement peut être changé par la définition d'un autre FlushMode), dans votre cas, en appelant flush, vous forcez le SQL pour être envoyé à la DB, mais vous avez toujours la DB transaction pour vous protéger, vous, lorsque vous appelez la restauration de la DB transaction sera annulée en supprimant les modifications effectuées à l'intérieur de lui-même et ainsi, rien ne sera fait enregistré. Notez que selon votre configuration de niveau d'isolation de transaction peut-être d'autres opérations seront en mesure de voir, d'une certaine façon la EntityA que vous avez enregistrées pour la courte période entre la sauvegarde et la restauration.
Notez également que la chasse d'eau est appelée automatiquement lorsque vous essayez de lire à partir de DB, dans 99% des cas, l'appelant explicitement n'est pas nécessaire. Une exception qui vient à l'esprit est que lorsque l'appareil de test automatique de la restauration de tests.
Lorsque vous appelez
session.save(a)
Hibernate, fondamentalement, se souvient de quelque part à l'intérieur de session que cet objet doit être enregistré. Il peut décider s'il veut émettreINSERT INTO...
immédiatement, quelques temps plus tard ou sur validation. C'est une amélioration de la performance, permettant d'Hibernation pour lot inserts ou de les éviter si la transaction est annulée.Lorsque vous appelez
session.flush()
, Hibernate est contraint d'émettre desINSERT INTO...
sur la base de données. L'entité est stocké dans la base de données, mais n'a pas encore commis. Selon le niveau d'isolation de transaction, il ne sera pas vu par les autres transactions en cours d'exécution. Mais maintenant, la base de données sait sur le dossier.Lorsque vous appelez
transaction.rollback()
, Hibernate rolls-sauvegarder la base de données de la transaction. Base de données gère la restauration, retirant ainsi l'objet nouvellement créé.Maintenant, considérons le scénario sans
flush()
. Tout d'abord, vous ne touchez jamais la base de données de sorte que la performance est meilleure et la restauration est fondamentalement un non-op. D'autre part si le niveau d'isolation de transaction estREAD UNCOMMITTED
, autres opérations peut voir enregistrement inséré avant même commit/rollback. Sansflush()
cela n'arrivera pas, à moins qu'Hibernate ne décide pas de laflush()
implicitement.Je pense que vous avez confondu avec
flush
etcommit
.flush()
synchronise l'état avec la base de données, mais il n'est pas de faire un commit. L'état est encore visible par transaction, de sorte que vous pouvez appeler à la restauration de restauration de.Donc la réponse à votre question: non, vous n'avez pas l'entité (a) dans la base de données.