2011-07-17 17 views
11

Se abbiamo un'applicazione web che hamodo migliore per gestire Hibernate sessioni in una stratificata un'applicazione Web Spring MVC

  • pesante UI (Spring MVC + JQuery con JSON)
  • Hibernate con annotazioni JPA è il dominio modello
  • estendere Primavera-fornito DAO per strato di codice DAO
  • JBOSS essere l'application server con Oracle come back-end
  • Origine dati (JNDI) connessione basata pooling (Non è un XA piuttosto locali sou dati RCE)
  • ha anche accesso a più fonti di dati (che si occupano di DB multipla)

vista comportamentale, un sacco di reperimento dei dati (70%) e l'aggiornamento dei dati di essere al 30%
Quali sarebbero le migliori pratiche per Quanto segue per utilizzare efficacemente le connessioni DB e anche vedere che non ci sono molte perdite nell'utilizzo della connessione?

  1. sarebbe meglio optare per DAO basati su template Hibernate?
  2. Che tipo di gestore delle transazioni sarebbe suggeribile e dovremmo optare per la gestione delle transazioni basata su AOPDove
  3. dove istanziare la sessione e dove chiudere le sessioni per consumare in modo efficace le connessioni dal pool di connessioni.
  4. E 'vero che abbiamo bisogno di gestire le transazioni dallo strato di servizio, ma ciò che accade a sessioni avrebbero in attesa per un tempo più lungo (non stiamo usando alcun OpenSessionInViewFilter)
  5. quale strato è meglio per gestire le eccezioni controllate (le eccezioni di business) ed eccezioni di runtime.

Ci scusiamo per la domanda un po 'più lunga, tuttavia vedo che questa è una query comune e ho provato a consolidarla. Apprezzo la tua pazienza e guida. Grazie per l'aiuto.

+0

E se pianifichiamo di utilizzare il partizionamento del database (intervallo tabella/partizione hash) nel back-end. Hibernate (o Shards? Non ancora in produzione!) Lo supporta? –

risposta

2
  • Utilizzare JPA EntityManager direttamente nei DAO. Essere sicuri di non contrassegnare come estesa
  • Preferisco <tx:annotation-driven /> e @Transactional - solo sul livello di servizio
  • il gestore delle transazioni apre e chiude le sessioni (se non ne esiste già nel thread) anche. Qui è bene sapere che le sessioni sono sessioni per richiesta. Ogni richiesta (= thread) ha un'istanza di sessione separata. Ma una connessione al database viene creata solo se ne è necessaria una, quindi anche se esiste un gestore delle transazioni attorno a tutti i metodi, le connessioni non necessarie non verranno aperte.
  • sola lettura transazioni - utilizzare @Transactional(readOnly=true) nei casi in cui v'è solo il recupero dei dati
  • caching - utilizzare la cache di 2 ° livello di sospensione di mettere le entità in memoria (invece di andare a prendere dal database ogni volta)
  • evitano OpenSessionInView e collezioni pigre. Questo è soggettivo, ma a mio parere tutti gli oggetti che escono dal livello di servizio devono essere inizializzati. Per le raccolte di piccole dimensioni (ad esempio l'elenco dei ruoli) è possibile avere raccolte interessanti. Per le raccolte più grandi utilizzare le query HQL.
+0

Sono d'accordo che è standard. Potresti per favore differenziare se abbiamo altri vantaggi in termini di prestazioni o utilizzo delle risorse con EntityManager. Inoltre, se vogliamo supportare il partizionamento orizzontale della tabella DB, quale sarebbe la tecnologia consigliata? –

+0

stesso. Se hai davvero bisogno di una sessione di sospensione o di una connessione raw, puoi ottenerla con 'entityManager.unwrap (Session.class)' – Bozho

15

questo suona come una bella tipica applicazione/Hibernate primavera, quindi vi consiglio di seguito le migliori pratiche attuali, che di recente ho delineato in another answer. In particolare:

  1. fare non estendere le classi di supporto Primavera DAO o usare HibernateTemplate. Utilizzare l'annotazione @Repository combinata con la scansione dei componenti e directly inject the SessionFactory nel DAO.
  2. Utilizzare Spring's HibernateTransactionManager e utilizzare sicuramente declarative transaction management tramite @Transactional come approccio predefinito.
  3. Lasciate Spring manage that. Aprirà le sessioni appena in tempo per le transazioni per impostazione predefinita, ma preferisce lo open session in view pattern abilitato da Spring's OpenSessionInViewFilter.
  4. Vedere # 3.
  5. Gestire sempre le eccezioni dove devono essere gestite - in altre parole, questa è una decisione di progettazione. Si noti, tuttavia, che il framework di transazione Spring per impostazione predefinita rolls back on unchecked exceptions, ma non selezionato, corrisponde al comportamento delle specifiche EJB. Assicurati di impostare le regole di rollback corrette (vedi link precedente) ovunque tu usi le eccezioni controllate.

Inoltre, utilizzare un pool di connessioni, ovviamente. Apache Commons DBCP è un'ottima scelta. "Non c'è molta perdita nell'uso della connessione" non è abbastanza. Devi avere zero perdite di connessione. A seconda di Spring, gestire le risorse aiuterà a garantire questo. Come per qualsiasi altro problema di prestazioni, non cercare di ottimizzare prima del tempo. Attendi fino a quando non vedi dove si trovano le aree problematiche e poi individua il modo migliore per risolverle individualmente. Poiché i colli di bottiglia saranno probabilmente correlati al database, controlla the performance chapter del riferimento Hibernate per avere un'idea di cosa stai affrontando. Copre i concetti importanti delle strategie di memorizzazione nella cache e di recupero.

+0

+1 Buona raccolta di informazioni rilevanti. –

+0

Preferirei EntityManager a SessionFactory anche se – Bozho

+0

@Bozho: Non importa veramente quale si utilizza, anche se non ho mai sentito un motivo convincente per usare EntityManager. –

Problemi correlati