2012-04-03 10 views
7

Io di solito uso il modello di gestione delle sessioni Hibernate ThreadLocal in progetti Web Java:Hibernate ThreadLocale Gestione della sessione compatibile con ForkJoinPool?

Il pattern Thread Local Session fa uso della classe java.lang.ThreadLocal per creare una sessione che è accessibile da una singola applicazione filo. Questo è particolarmente utile nelle applicazioni multithread , come le applicazioni web.

Nei progetti a implementare questo con

<property name="current_session_context_class">thread</property> 

nel hibernate.xml e utilizzando SessionFactory.getCurrentSession() per ottenere una sessione ogni volta che ho bisogno di uno.

Ora ho un programma che è non un servlet, ma esegue l'elaborazione parallela pesante e l'interazione del database.

Voglio implementarlo con ForkJoinPool. Ora mi chiedo se sia un errore utilizzare la gestione della sessione ThreadLocal di Hibernate in questo scenario. Per quanto ho capito, ForkJoinPool utilizza un numero inferiore di thread e li condivide tra le attività in esecuzione mentre altre attività stanno dormendo. (Motivato dall'arresto/annoying delle connessioni "task in transaction",) Voglio chiudere() ogni Hibernate Session dopo un'unità di lavoro

Quindi .. quando chiamo HibernateSessionFactory.getThreadLocalSession(). Close() al fine del mio compito - e l'attività viene eseguita in un ForkJoinPool - sorgeranno problemi Devo abbandonare il modello ThreadLocal per i calcoli paralleli pesanti e gestire le Sessioni me

Grazie in anticipo per eventuali risposte

+0

Si sta utilizzando SessionFactory.getCurrentSession() o .openSession() per ottenere gli oggetti Session? Se getCurrentSession, quale CurrentSessionContext stai usando? Sto indovinando ThreadLocalSessionContext, ma ti stai riferendo ad esso come un 'pattern' in contrasto con una classe. – sharakan

+0

Grazie per l'esame di questo .. Ho aggiornato la domanda con maggiori dettagli. – alfonx

risposta

4

Utilizzando??. ThreadLocalSessionContext potrebbe essere problematico per te, ma dipende da ciò che i tuoi compiti stanno facendo.

A (javadocs) è destinato all'uso nei casi in cui le attività generano altre attività (il fork) e aspettano che vengano completate (join). Durante l'attesa, il thread che eseguiva l'attività padre può essere riutilizzato per eseguire un'attività secondaria. Secondo javadocs per ThreadLocalSessionContext, lo Session viene chiuso quando si esegue il commit di una transazione ottenuta (ad esempio, c'è sempre una transazione per Session).

Quindi, se si dispone di un'attività "padre" che chiama sessionFactory.getCurrentSession() e fa alcune cose, quindi chiama commit(), la Sessione viene chiusa e non vi è alcun pericolo di interazione inappropriata.

Tuttavia, se si depongono le uova le attività per bambini dopo aver chiamato .getCurrentSession() e prima di chiamare .commit(), si può incorrere in problemi a causa di altri compiti possono eseguire su questa discussione, e .getCurrentSession() dovrebbe restituire la sessione utilizzato dal task genitore. Questo non è quasi certamente quello che vuoi, perché i compiti dei bambini dovrebbero presumibilmente fare la stessa cosa l'uno con l'altro, e non vorresti che uno condividesse arbitrariamente lo stato Session con il genitore mentre altri no.

Quindi, in sintesi, si dovrebbe:

  • Non chiamare session.close() se si ottiene il Session da .getCurrentSession(), perché è la responsabilità del CurrentSessionContext a che fare con questo.
  • Essere in una relazione impegnata prima di avere figli .... Voglio dire, chiamare .commit() prima di generare attività bambini.

Come nota a piè di pagina, ho trovato this wiki page un'utile lettura sull'argomento.

Problemi correlati