2010-03-29 4 views
13

Vous vous demandez simplement si commencer une nouvelle transaction dans Hibernate alloue réellement une connexion à la base de données?beginTransaction dans Hibernate alloue-t-il une nouvelle connexion DB?

Je m'inquiète b/c notre serveur commence une nouvelle transaction pour chaque demande reçue, même si cette demande n'interagit pas avec le DB. Nous considérons les connexions DB comme un goulot d'étranglement majeur, et je me demande si je devrais prendre le temps de réduire la portée de mes transactions.

Recherché partout et n'a pas été en mesure de trouver une bonne réponse. Le code très simple est ici:

SessionFactory sessionFactory = (SessionFactory) Context.getContext().getBean("sessionFactory"); 
    sessionFactory.getCurrentSession().beginTransaction(); 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO); 

merci beaucoup! un

Répondre

8

(Mis à jour par le commentaire de Pascal Thivent)

Chaque Session crée une connexion de base de données s'il est nécessaire pour que - par exemple si une transaction est démarrée. La connexion n'est pas ouverte avec la simple création de la session.

Pour remédier à cela, vous pouvez utiliser un connecetion pool afin que les connexions soient réutilisées. Ou vous pouvez vous assurer (comme il semble que vous l'avez fait) qu'aucune transaction n'est lancée automatiquement.

(This traite de transactions en lecture seule Jetez un coup d'oeil..)

+0

Merci, nous utilisons déjà un pool de connexion. En ne démarrant pas une transaction par défaut, nous avons pu réduire massivement la charge sur notre base de données. – illscience

+1

En fait, la connexion est paresseuse dans une 'Session'. Voir ma réponse pour plus de détails. –

+0

@Pascal Thivent hm, intéressant, et logique :) @illscience s'il vous plaît changer la réponse acceptée – Bozho

14

Selon la section 11.1. Session and transaction scopes de la documentation Hibernate:

A SessionFactory est un cher à créer, threadsafe objet, destiné à être partagé par tous les threads d'application . Il est créé une fois, généralement au démarrage de l'application, à partir d'une instance Configuration.

Un Session est un bon marché, objet non threadsafe qui devrait être utilisé une fois, puis mis au rebut pour: une seule demande , une conversation ou une seule unité de travail. A Session pas obtenir un JDBC Connection, ou Datasource, sauf si nécessaire. Il ne consommera aucune ressource jusqu'à ce que utilisé.

Afin de réduire la contention de verrouillage dans la base de données, une transaction de base de données doit être aussi courte que possible. Long transactions de base de données permettra d'éviter votre application de mise à l'échelle à une charge hautement concurrente . Il n'est pas recommandé que vous déteniez une transaction de base de données ouverte pendant que l'utilisateur pense jusqu'à ce que l'unité de travail soit terminée.

Maintenant, pour répondre à votre question:

  • obtenir un Session ne pas acquérir immédiatement une connexion (la connexion est paresseux chargé)
  • mais appelant beginTransaction() entraînera la charge de la connexion pour les données Session
  • les appels suivants réutilisera le même connection

Examinez org.hibernate.impl.SessionImpl#beginTransaction() et passez le code en revue pour plus de détails.

+0

+1, bien sûr (15chrs) – Bozho

+0

@Bozho Merci! –

+0

Remets. Bonne réponse –

Questions connexes