Pourquoi ai-je besoin de Transaction dans Hibernate pour les opérations en lecture seule?
La transaction suivante met-elle un verrou dans la base de données?
Exemple de code à extraire de DB:
Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here
tx.commit() // why tx.commit? I don't want to write anything
Puis-je utiliser à la session.close()
place de tx.commit()
?
Réponses:
Vous pourriez en fait avoir des raisons de marquer les transactions en lecture seule.
autocommit=true
si une option différente n'a pas été définie explicitement.@Transactional(readonly=true)
, Spring définira la transaction JDBC en mode lecture seule, ainsi vous dicterez s'il est réellement possible d'écrire dans la base de données dans le cadre de cette transaction. Si votre architecture est encombrante et que certains membres de l'équipe peuvent choisir de placer la requête de modification là où elle n'est pas attendue, cet indicateur vous indiquerait l'endroit problématique.Pour résumer, vous pouvez aller dans les deux sens, mais vous devez comprendre les conséquences.
la source
Toutes les instructions de base de données sont exécutées dans le contexte d'une transaction physique, même lorsque nous ne déclarons pas explicitement les limites de transaction (BEGIN / COMMIT / ROLLBACK).
Si vous ne déclarez pas explicitement les limites de transaction, chaque instruction devra être exécutée dans une transaction distincte (
autocommit
mode). Cela peut même conduire à l'ouverture et à la fermeture d'une connexion par instruction, sauf si votre environnement peut gérer la liaison connexion par thread.La déclaration d'un service comme
@Transactional
vous donnera une connexion pour toute la durée de la transaction, et toutes les instructions utiliseront cette connexion d'isolation unique. C'est bien mieux que de ne pas utiliser de transactions explicites en premier lieu.Sur les applications volumineuses, vous pouvez avoir de nombreuses demandes simultanées et la réduction du taux de demandes d'acquisition de connexion à la base de données améliorera certainement les performances globales de vos applications.
JPA n'applique pas les transactions sur les opérations de lecture. Seules les écritures finissent par lancer une exception de transaction requise au cas où vous oublieriez de démarrer un contexte transactionnel. Néanmoins, il est toujours préférable de déclarer les limites des transactions, même pour les transactions en lecture seule (dans Spring
@Transactional
vous permet de marquer les transactions en lecture seule, ce qui présente un grand avantage en termes de performances).la source
Les transactions placent en effet des verrous sur la base de données - les bons moteurs de base de données gèrent les verrous simultanés de manière judicieuse - et sont utiles avec une utilisation en lecture seule pour s'assurer qu'aucune autre transaction n'ajoute de données qui rendent votre vue incohérente. Vous voulez toujours une transaction (bien qu'il soit parfois raisonnable d'ajuster le niveau d'isolement, il vaut mieux ne pas le faire pour commencer); si vous n'écrivez jamais dans la base de données pendant votre transaction, la validation et l'annulation de la transaction s'avèrent être les mêmes (et très bon marché).
Maintenant, si vous avez de la chance et que vos requêtes contre la base de données sont telles que l'ORM les mappe toujours sur des requêtes SQL uniques, vous pouvez vous en sortir sans transactions explicites , en vous appuyant sur le comportement d'autocommit intégré de la base de données, mais les ORM sont des systèmes relativement complexes il n'est donc pas du tout sûr de s'appuyer sur un tel comportement à moins que vous ne travailliez beaucoup plus à vérifier ce que fait réellement l'implémentation. Il est beaucoup plus facile d'écrire les limites de transaction explicites (surtout si vous pouvez le faire avec AOP ou une technique similaire basée sur l'ORM; à partir de Java 7, try-with-resources pourrait être utilisé aussi je suppose).
la source
Peu importe que vous lisiez uniquement ou non - la base de données doit toujours garder une trace de votre jeu de résultats, car d'autres clients de base de données peuvent vouloir écrire des données qui modifieraient votre jeu de résultats.
J'ai vu des programmes défectueux pour tuer d'énormes systèmes de base de données, car ils lisent simplement des données, mais ne s'engagent jamais, forçant le journal des transactions à croître, car la base de données ne peut pas libérer les données de transaction avant un COMMIT ou un ROLLBACK, même si le client n'a rien fait Pendant des heures.
la source